Using http://localhost for local development is fine most of the time, except in some special cases. This post explains when you need to run your local development site with HTTPS.


![Maud Nalpas](https://web.dev/images/authors/maudnalpas.jpg) Maud Nalpas [GitHub](https://github.com/maudnals) [LinkedIn](https://www.linkedin.com/in/maudnalpas) [Bluesky](https://bsky.app/profile/maudnals.bsky.social)

<br />

Also see: [How to use HTTPS for local development](https://web.dev/articles/how-to-use-local-https.md.txt).

*In this post, statements about `localhost` are valid for `127.0.0.1` and `[::1]` as well, since they both describe the local computer address, also called "loopback address". To keep things simple, the port number isn't specified.*
*So when you see `http://localhost`, read it as `http://localhost:{PORT}` or `http://127.0.0.1:{PORT}`.*

When developing locally, use `http://localhost` by default. Service Workers,
Web Authentication API, and more work. However, in the following cases, you
need HTTPS for local development:

- Debugging mixed-content issues
- Using HTTP/2 and later
- Using third-party libraries or APIs that require HTTPS
- Using a custom hostname

![A list of cases when you need to use HTTPS for local development.](https://web.dev/static/articles/when-to-use-local-https/image/a-list-cases-you-need.png) When to use HTTPS for local development.

If you need HTTPS for local development, check out
[How to use HTTPS for local development](https://web.dev/articles/how-to-use-local-https.md.txt).

## Why your development site should behave securely

To avoid running into unexpected issues, you want your local development site to behave as much as possible like your production website. So, if your production website uses HTTPS, you want your local development site to behave **like an HTTPS site**.

> [!WARNING]
> **Warning:** If your production website doesn't use HTTPS, [update it now](https://web.dev/articles/why-https-matters.md.txt).

## Use `http://localhost` by default

Browsers treat `http://localhost` in a special way:
**although it's HTTP, it mostly behaves like an HTTPS site**.

On `http://localhost`, Service Workers, Sensor APIs, Authentication APIs,
Payments, and [other features that require certain security guarantees](https://developer.mozilla.org/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts)
are supported and behave exactly like on an HTTPS site.

## When to use HTTPS for local development

You may encounter special cases where `http://localhost` *doesn't* behave like
an HTTPS site. Alternatively, you may want to use a custom site name that's not
`http://localhost`.

You need to use HTTPS for local development in the following cases:

- You need to debug locally an issue that only occurs on an HTTPS website but not on an HTTP site, not even `http://localhost`, such as a [mixed-content](https://developer.mozilla.org/docs/Web/Security/Mixed_content) issue.
- You need to locally test or reproduce a behaviour specific to HTTP/2 or newer. For example, if you need to test loading performance on HTTP/2 or newer. Insecure HTTP/2 or newer is not supported, not even on `localhost`.
- You need to locally test third-party libraries or APIs that require HTTPS (for example OAuth).
- You're not using `localhost`, but a custom hostname for local development, for example `mysite.example`. Typically, this means you've overridden your local hosts file:

  ![Screenshot of a terminal editing a hosts file](https://web.dev/static/articles/when-to-use-local-https/image/screenshot-a-terminal-ed-4f35b6d0cd9b5.jpg) Editing a hosts file to add a custom hostname.

  <br />

  In this case, Chrome, Edge, Safari, and Firefox by default do *not* consider `mysite.example` to be secure, even though it's a local site. So it won't behave like an HTTPS site.
- Other cases! This is not an exhaustive list, but if you encounter a case that's not listed here, you'll know: things will break on `http://localhost`, or it won't quite behave like your production site. 🙃

**In all of these cases, you need to use HTTPS for local development.**

<br />

> [!TIP]
> HTTPS used to be necessary to locally set a cookie that is `Secure`, or `SameSite:none`, or has the `__Host` prefix. It is no longer the case.

<br />

## How to use HTTPS for local development

If you need to use HTTPS for local development, head over to [How to use HTTPS for local development](https://web.dev/articles/how-to-use-local-https.md.txt).

## Tips if you're using a custom hostname

If you're using a custom hostname, for example, editing your hosts file:

- Don't use a bare hostname like `mysite`, because if there's a real [top-level domain (TLD)](https://wikipedia.org/wiki/Top-level_domain) that happens to have the same name (`mysite`), you'll run into issues. It's not that unlikely: in 2020, there are over [1,500 TLDs](https://data.iana.org/TLD/tlds-alpha-by-domain.txt), and the list is growing. `coffee`, `museum`, `travel`, and many large company names (maybe even the company you're working at!) are TLDs.
- Only use domains that are yours, or that are reserved for this purpose. If you don't have a domain of your own, you can use either `test` or `localhost` (`mysite.localhost`). `test` doesn't have special treatment in browsers, but `localhost` does: Chrome and Edge support `http://<name>.localhost` out of the box, and it behaves securely when localhost does. Try it out: run any site on localhost and access `http://<whatever name you like>.localhost:<your port>` in Chrome or Edge. This may soon be possible in Firefox and [Safari](https://bugs.webkit.org/show_bug.cgi?id=160504) as well. The reason you can do this (have subdomains like `mysite.localhost`) is because `localhost` is not just a hostname: it's also a full TLD, like `com`.

## Learn more

- [Secure contexts](https://developer.mozilla.org/docs/Web/Security/Secure_Contexts)
- [localhost as a secure context](https://www.w3.org/TR/secure-contexts/#localhost)
- [localhost as a secure context in Chrome](https://www.chromestatus.com/feature/6269417340010496)

*With many thanks for contributions and feedback to all reviewers. Special
thanks to Ryan Sleevi, Filippo Valsorda, Milica Mihajlija, Rowan Merewood and
Jake Archibald.*