How-to

How to Generate a Self-Signed Certificate for Local Development

For local development on localhost, a self-signed certificate provides real TLS encryption without needing a publicly trusted CA, which can't issue certificates for private/non-public hostnames anyway.

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout localhost.key -out localhost.crt -days 365 \
  -subj "/CN=localhost"

Getting rid of the browser warning locally

The certificate itself works correctly, but your browser will still show a warning since it isn't signed by a trusted CA. To remove the warning specifically on your own development machine, add the certificate to your OS or browser's local trust store manually (each OS has its own certificate management tool for this) — never do this on a machine other than your own for a certificate you don't control.

A more convenient alternative: mkcert

The mkcert tool automates this entire process — generating a local certificate authority, installing it in your system trust store automatically, and issuing locally-trusted certificates for localhost or any development domain, removing the manual trust-store steps above.

What to do if your browser still shows a warning after trusting the certificate

If a browser continues showing a warning despite adding the certificate to your system trust store, confirm you added it to the correct store (some systems distinguish between user and system-wide trust) and restart the browser completely, since some browsers cache trust decisions and don't immediately recognize a newly trusted certificate.

How mkcert simplifies this entire process compared to manual OpenSSL commands

mkcert automates creating a local certificate authority, installing it into your system and browser trust stores, and issuing locally-trusted certificates for any development domain, collapsing what would otherwise be several manual OpenSSL commands and manual trust-store configuration into a single command.

What Subject Alternative Name entries you should include for local development specifically

Including both localhost and 127.0.0.1 as SAN entries, along with any custom local domain you're using (like myapp.local), covers the range of ways you might access your local development server, avoiding a hostname mismatch depending on exactly how you type the URL.

How to generate a certificate valid for a longer period during extended local development

Adding the -days flag with a larger value (365 or more) when generating a self-signed certificate with OpenSSL avoids needing to regenerate it every few months during a long-running local development project, though mkcert's locally-trusted certificates typically default to a longer validity period already.

Why some frameworks and tools have their own built-in local HTTPS options

Some development frameworks and tools bundle their own local HTTPS certificate generation directly (Vite, Next.js, and others increasingly offer a built-in flag), reducing the need for a separate manual certificate generation step — worth checking your specific framework's documentation before setting up certificates manually.

What to do if your local certificate needs to be trusted on a second device for testing

For testing from a second device (a phone, a tablet) on the same local network, that device needs its own separate trust configuration for your local CA or certificate — mkcert specifically supports this multi-device scenario more smoothly than manually managing individual self-signed certificates.

How self-signed certificate warnings differ from a genuinely invalid certificate warning

A self-signed certificate warning specifically indicates an untrusted issuer, distinct from other certificate warnings like an expired date or hostname mismatch — recognizing this specific warning type helps confirm you're dealing with the expected, intentional local development scenario rather than an actual configuration problem.

A closing note on why mkcert has become the generally recommended default

For nearly any local development HTTPS need today, mkcert's combination of simplicity and proper local trust handling has made it the generally recommended default over manually running individual OpenSSL commands, reserving the manual approach for genuinely unusual cases mkcert doesn't cover.

A final word of caution worth keeping in mind

Keeping your local development certificates separate from anything resembling production configuration, clearly named and stored, prevents the specific, embarrassing mistake of accidentally deploying a self-signed development certificate to a production environment.