vite-firebase-local-gateway
v0.1.0
Published
Local HTTPS gateway and CLI for Vite apps, Firebase Emulator and host-based dev routing.
Maintainers
Readme
Vite Firebase Local Gateway
Local HTTPS gateway and CLI for Vite apps, Firebase Emulator and other local services.
This tool is for local development only. It is not a production reverse proxy.
Why It Exists
Vite + Firebase Emulator projects often turn into localhost juggling:
localhost:5173 -> Vite
localhost:4000 -> Firebase Emulator UI
localhost:8080 -> Firestore Emulator
localhost:9099 -> Auth Emulator
localhost:5001 -> Functions EmulatorThat makes cookies, redirects, CORS, OAuth callbacks, service workers and SDK config behave differently from production. This gateway gives each local service a normal HTTPS host while still routing everything to containers or processes on your machine.
https://app.local.test -> Vite app
https://firebase.local.test -> Firebase Emulator UI and APIs
https://api.local.test -> local HTTP serviceFeatures
- HTTPS local reverse proxy
- HTTP to HTTPS redirect
- Host and path based routing
- Vite app, Firebase Emulator and generic HTTP app routing
- Firebase Emulator UI config rewriting
- WebSocket proxying
- Dynamic local certificates through
mkcert - Basic Auth as a plugin
- External config and plugin loading
- Docker Compose friendly
- Health endpoint at
/__healthand legacy/_proxy/health
Install
Run directly:
npx vite-firebase-local-gatewayor:
npx vite-firebase-local-gateway startInstall in a project:
npm install --save-dev vite-firebase-local-gatewayThen add:
{
"scripts": {
"gateway": "vite-firebase-local-gateway start"
}
}Quick Start
Create gateway.config.js:
/** @type {import("vite-firebase-local-gateway").GatewayConfig} */
export default {
domains: ["app.local.test", "firebase.local.test", "api.local.test"],
routes: [
{
name: "viteApp",
target: "http://localhost:5173",
hostStartsWith: "app",
},
{
name: "api",
target: "http://localhost:8080",
hostStartsWith: "api",
},
],
};Start the gateway:
npx vite-firebase-local-gateway start --localDefaults:
HTTP redirect: http://localhost:8080
HTTPS proxy: https://localhost:4433
Healthcheck: http://localhost:8080/__healthWhen using host ports 80 and 443 in Docker, browse to the domain directly:
https://app.local.test
https://firebase.local.testConfig
The CLI looks for gateway.config.js, gateway.config.mjs or gateway.config.cjs in the current working directory. You can also pass a path:
npx vite-firebase-local-gateway start --config ./config/gateway.config.jsSee gateway.config.example.js and gateway.config.example.ts. For a Docker-oriented example, see examples/gateway.config.js and examples/docker-compose.basic-auth.yml.
The config can map services without editing package internals:
export default {
routes: [
{ name: "viteApp", target: "http://web:3000", hostStartsWith: "app" },
{ name: "api", target: "http://api:8080", hostStartsWith: "api" },
{ name: "admin", target: "http://admin:3000", hostStartsWith: "admin" },
],
};The built-in Firebase plugin reads firebase.json and maps emulator services. In Docker, it assumes the Firebase service host is firebase; with --local, it uses localhost. You can override that:
export default {
firebaseHost: "firebase",
};Basic Auth
Basic Auth is implemented as a plugin and reads credentials from environment variables:
PROXY_BASIC_AUTH_USER=local-user
PROXY_BASIC_AUTH_PASS=replace-with-a-local-secret
PROXY_BASIC_AUTH_REALM=Firebase Local GatewayCopy the example:
cp .basicAuth.env.example .basicAuth.envDo not commit .basicAuth.env.
In Docker Compose:
services:
gateway:
environment:
PROXY_BASIC_AUTH_USER: "local-user"
PROXY_BASIC_AUTH_PASS: "replace-with-a-local-secret"By default, the plugin protects hosts where domain.startsWith("firebase") or domain.startsWith("assistanthub").
If PROXY_BASIC_AUTH_USER or PROXY_BASIC_AUTH_PASS are missing or empty, the Basic Auth plugin is disabled (no-op).
Plugins
Plugins export route rules and optional override hooks:
export const serviceRules = {
reports: (domain) => domain.startsWith("reports"),
};
export const routeTable = {
reports: "http://reports:3000",
};Load an external plugin from config:
export default {
plugins: ["./examples/plugins/custom-plugin.js"],
};See docs/PLUGINS.md and examples/plugins/custom-plugin.js.
TypeScript users can import useful types:
import type { GatewayConfig, GatewayPlugin, ServiceRules, RouteTable } from "vite-firebase-local-gateway";The config and plugin APIs are intentionally small in 0.1.0 and may change while the package is still early.
Docker
See examples/docker-compose.basic-auth.yml.
The gateway does not require installing openssl in the container.
Typical port mapping:
ports:
- "80:8080"
- "443:4433"The gateway exposes /__health (and legacy /_proxy/health) if you want to add healthchecks in your own Compose.
Using a versionable config file in Docker is recommended:
volumes:
- ./gateway.config.js:/workspace/gateway.config.js:ro
command: npx --yes vite-firebase-local-gateway start --config /workspace/gateway.config.jsLocal Certificate Trust
The gateway generates a local CA and certificates under certs/. Generated certificates are ignored by git and should not be published.
Start the gateway once so it creates certs/rootCA.pem, then trust the CA.
macOS:
npm run trust:macosDebian/Ubuntu and Fedora/RHEL:
npm run trust:linuxYou can also pass a custom CA path:
bash scripts/trust-cert-macos.sh ./certs/rootCA.pem
bash scripts/trust-cert-linux.sh ./certs/rootCA.pemRestart browsers that were already open.
Troubleshooting
firebase.json not found: run from a directory that containsfirebase.json, mount it into the Docker working directory, or pass a config that disables built-in plugins withuseBuiltinPlugins: false.- Browser certificate warning: start the gateway once, run the trust script for your OS, then restart the browser.
- Basic Auth always rejects: check
PROXY_BASIC_AUTH_USERandPROXY_BASIC_AUTH_PASSin.basicAuth.env. - Host routes to the wrong service: route matching uses the first matching
serviceRulesentry after plugins are merged; make route names unique. - Docker health is unhealthy: verify
http://127.0.0.1:8080/__healthfrom inside the gateway container.
Development
npm install
npm run typecheck
npm run build
npm run proxy -- --localPublishing
See docs/publishing.md.
Short version:
npm run typecheck
npm run build
npm pack --dry-run
npm login
npm version patch
npm publish