
Local HTTPS on Mac with mkcert (Vite, Next.js & .test Domains)
Install mkcert on Mac, trust the local CA, and generate HTTPS certs for localhost and .test domains. Includes Vite, Next.js, Docker, and NET::ERR_CERT_AUTHORITY_INVALID fixes.
mkcert ssl local is the fastest way to get browser-trusted HTTPS on Mac for localhost, 127.0.0.1, and custom .test domains - no self-signed warnings, no tunneling.
mkcert ssl local - copy-paste setup (Mac)
Run these three commands in Terminal:
brew install mkcert
mkcert -install
mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem localhost 127.0.0.1 ::1 myproject.test "*.myproject.test"Then point your dev server at certs/local-cert.pem and certs/local-key.pem. Open https://localhost:3000 or https://myproject.test - the padlock should be green.
| Step | Command | What it does |
|---|---|---|
| 1 | brew install mkcert | Installs the mkcert CLI |
| 2 | mkcert -install | Creates a local CA trusted by macOS + browsers |
| 3 | mkcert localhost … | Generates a signed cert + private key |
Still seeing NET::ERR_CERT_AUTHORITY_INVALID? → Fix mkcert certificate errors Changed /etc/hosts or DNS? → Flush DNS on Mac first.
Developing a PWA and Service Workers refuse to activate? Geolocation, Clipboard, and WebRTC APIs require a secure context (HTTPS). mkcert fixes this permanently on your machine in under two minutes.
Why mkcert ssl local beats alternatives
| Approach | Browser trust | Setup time | Best for |
|---|---|---|---|
| mkcert | Trusted padlock | ~2 min | Daily local dev |
| Self-signed OpenSSL | Warnings every time | ~10 min | Quick one-off tests |
| ngrok / Cloudflare Tunnel | Public HTTPS URL | ~5 min | Webhooks, mobile testing |
| Caddy auto-HTTPS | Local trust | ~15 min | Always-on local proxy |
Use mkcert when you want https://myproject.test to behave exactly like production HTTPS on your Mac.
Quick setup: mkcert SSL local on Mac
For most local development projects, this is the fastest path:
- Install mkcert with Homebrew.
- Run
mkcert -installonce to trust the local certificate authority. - Generate certificates for
localhost,127.0.0.1,::1and your custom.testdomains. - Point your dev server to the certificate and key files.
- Restart the browser if it still shows a certificate warning.
brew install mkcert
mkcert -install
mkdir -p certs
mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem localhost 127.0.0.1 ::1 myproject.test "*.myproject.test"You can now configure your server with certs/local-cert.pem and certs/local-key.pem.
Why HTTPS locally?
APIs that require HTTPS
Many modern web APIs only work in secure contexts (HTTPS):
- Service Workers: Required for PWAs
- Geolocation API: GPS location
- Clipboard API: Copy/paste
- WebRTC: Video/audio
- Web Bluetooth: Bluetooth devices
- Push Notifications: Push API
Other advantages
- Dev/prod parity: Same behavior everywhere
- Secure cookies: Test Secure and SameSite attributes
- HTTP/2: Requires HTTPS
- Credibility: No browser warnings
Installing mkcert
What is mkcert?
mkcert is a tool created by Filippo Valsorda that:
- Creates a local certificate authority (CA)
- Installs this CA in your system and browsers
- Generates certificates signed by this CA
Result: your local certificates are recognized as valid.
Installation on Mac
# With Homebrew
brew install mkcert
# Install root certificates
mkcert -installYou'll see a message asking for your password to install the CA in the system keychain.
Verify installation
mkcert -CAROOTShows the folder containing your local CA.
Creating certificates
For localhost
mkcert localhost 127.0.0.1 ::1Creates two files:
localhost+2.pem: The certificatelocalhost+2-key.pem: The private key
For a custom domain
mkcert myproject.testWith wildcard (subdomains)
mkcert myproject.test "*.myproject.test"Allows using api.myproject.test, admin.myproject.test, etc.
All-in-one certificate
mkcert localhost 127.0.0.1 ::1 myproject.test "*.myproject.test"Configuring your server
Node.js / Express
const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();
const options = {
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem')
};
https.createServer(options, app).listen(3000, () => {
console.log('HTTPS server running on https://localhost:3000');
});Vite (recommended config)
See also: mkcert + Vite & Next.js local HTTPS for a full monorepo setup.
// vite.config.js
import { defineConfig } from 'vite';
import fs from 'fs';
import path from 'path';
const certDir = path.resolve(__dirname, 'certs');
export default defineConfig({
server: {
host: 'myproject.test',
https: {
key: fs.readFileSync(path.join(certDir, 'local-key.pem')),
cert: fs.readFileSync(path.join(certDir, 'local-cert.pem')),
},
},
});Add 127.0.0.1 myproject.test to your hosts file (see edit hosts on Mac), then run npm run dev and open https://myproject.test:5173.
Next.js 15+ (experimental HTTPS)
next dev --experimental-https --experimental-https-key certs/local-key.pem --experimental-https-cert certs/local-cert.pemRecent Next.js versions can run the development server over HTTPS directly. If your setup needs custom routing or a proxy, use a custom server instead:
// next.config.js with custom server
const { createServer } = require('https');
const { parse } = require('url');
const next = require('next');
const fs = require('fs');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const httpsOptions = {
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem')
};
app.prepare().then(() => {
createServer(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
}).listen(3000);
});Webpack Dev Server
// webpack.config.js
const fs = require('fs');
module.exports = {
devServer: {
https: {
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem')
}
}
};Using with custom domains
Configure the hosts file
To use myproject.test instead of localhost:
# /etc/hosts
127.0.0.1 myproject.test
127.0.0.1 api.myproject.testCreate the corresponding certificate
mkcert myproject.test "*.myproject.test"Configure the server
Use the newly generated files in your server configuration.
Advanced use cases
Laravel Valet
Valet integrates mkcert natively:
valet secure myprojectThat's it! Valet automatically generates and configures certificates.
Docker
# docker-compose.yml
services:
web:
volumes:
- ./certs:/etc/nginx/certs:ro
environment:
- VIRTUAL_HOST=myproject.test
- CERT_NAME=myproject.testMAMP Pro
- Preferences > Hosts
- Select your host
- SSL > Enable
- Import your mkcert certificates
Troubleshooting
"NET::ERR_CERT_AUTHORITY_INVALID"
The CA is not installed in the browser.
mkcert -installThen restart your browser. If the error persists after reinstalling the CA, follow the dedicated walkthrough on how to fix NET::ERR_CERT_AUTHORITY_INVALID for hostname-coverage and stale-certificate causes.
Chrome still ignores the certificate
Chrome may need a full restart:
# Mac
killall "Google Chrome"
open -a "Google Chrome"If Chrome still shows NET::ERR_CERT_AUTHORITY_INVALID, confirm the certificate covers the exact hostname in the address bar. A certificate for localhost will not automatically cover myproject.test.
Firefox doesn't recognize the CA
Firefox uses its own certificate store. Install it manually:
- Preferences > Privacy & Security > Certificates
- View Certificates > Authorities > Import
- Select rootCA.pem from
mkcert -CAROOT
Best practices
Certificate organization
~/certs/
├── localhost/
│ ├── localhost+2.pem
│ └── localhost+2-key.pem
├── myproject.test/
│ ├── myproject.test+1.pem
│ └── myproject.test+1-key.pem
└── README.mdNever commit keys
# .gitignore
*.pem
certs/Keep the certificate generation command in your README or setup script, but keep the generated key files out of Git.
Project setup script
#!/bin/bash
# setup-certs.sh
mkdir -p certs
cd certs
mkcert localhost 127.0.0.1 ::1 myproject.test "*.myproject.test"
echo "Certificates created in ./certs/"Alternatives to mkcert
Self-signed certificates (not recommended)
Work but generate constant browser warnings.
Tunnels (ngrok, localtunnel)
Expose your localhost on the Internet with HTTPS. Useful for mobile testing or webhooks.
Caddy
Web server with automatic HTTPS, even locally.
Conclusion
HTTPS locally is no longer optional in 2026. With mkcert, installation takes 2 minutes and saves you hours of frustration with modern APIs. Combine it with .test domains managed via ToggleHosts for a professional development environment.
Frequently Asked Questions
Certain modern APIs (Service Workers, Geolocation, Clipboard, WebRTC) only work over HTTPS. Plus, it avoids differences between dev and production.
mkcert is a tool that creates a local certificate authority and generates trusted SSL certificates for your development domains.
For local development, yes. Never use mkcert in production. The certificates are only valid on your machine.
After installing mkcert, run 'mkcert localhost' to create certificates, then configure your server to use them.
Related Articles
How to Edit the Hosts File on Mac (/etc/hosts)Editing the hosts file
How to Edit the Hosts File on Mac (/etc/hosts)
6 min read
Fix mkcert NET::ERR_CERT_AUTHORITY_INVALIDTroubleshooting
Fix mkcert NET::ERR_CERT_AUTHORITY_INVALID
5 min read
Fix NET::ERR_CERT_COMMON_NAME_INVALID with Hosts File (2026)Troubleshooting
Fix NET::ERR_CERT_COMMON_NAME_INVALID with Hosts File (2026)
4 min read