Getting started
Installing Fyra
The CLI is a single self-contained binary. Install it globally once and you're done. Works on macOS, Linux, and Windows.
Install the CLI
terminal
$ curl -fsSL https://fyra.sh/install.sh | sh
Installs fyra to /usr/local/bin.
Create an account
terminal
$ fyra register
Email: you@example.com
Password: ········
Confirm password: ········
Account created. Check your email to verify your address.
Log in
terminal
$ fyra login
Email: you@example.com
Password: ········
Logged in successfully.
Your token is saved to ~/.fyra/config.yaml.
Already have an account? Skip registration and run fyra login directly.
Getting started
Your first deploy
Two commands: fyra create registers the app, fyra push sends it to the network.
Go to your project directory
terminal
$ cd my-site/dist
Create the app
terminal
$ fyra create --appname my-site
Created app: my-site
Run 'fyra push' to deploy this directory.
Writes .deploy.yaml to your project. Omit --appname to get a random slug like quiet-river.
Push it live
terminal
$ fyra push
Scanning my-site...
Packing 24 files (840.0 KB)
Uploading... 840.0 KB sent
Deploying on server...
Done: https://my-site.apps.fyra.sh
Files are tarballed in memory, sent over gRPC, and the CDN updates automatically.
Subsequent deploys? Just fyra push again. That's the whole loop.
Domains
Custom domains
Three steps: register the domain with Fyra, add a CNAME at your registrar, then verify.
Register the domain
terminal
$ fyra set-domain shop.example.com
Custom domain set to shop.example.com.
Point your CNAME for shop.example.com → shop-example-com.ignite.fyra.sh
Run 'fyra check-domains' to verify once DNS propagates.
Add the CNAME record
At your registrar / DNS provider, add:
dns record
Type Host Value
CNAME shop.example.com shop-example-com.ignite.fyra.sh
Apex domains are also supported. Cloudflare users should enable Proxied mode.
Verify and activate
terminal
$ fyra check-domains
Have you added a CNAME for shop.example.com → shop-example-com.ignite.fyra.sh? [y/N] y
✓ CNAME verified.
Certificate status: provisioning…
✓ Custom domain is live at https://shop.example.com
To revert to slug.apps.fyra.sh, run fyra remove-domain.
Domains
SSL & HTTPS
Every Fyra site is HTTPS-only. Certificates are issued and renewed automatically.
Free subdomain certificates
*.apps.fyra.sh uses a wildcard certificate managed by Fyra. Nothing for you to do.
Custom domain certificates
Let's Encrypt issues a certificate automatically when the CNAME is detected. fyra check-domains waits for the cert to land (about 2 minutes).
certificate lifecycle
CNAME verified → cert requested → cert issued → HTTPS live
Automatic renewal
Certificates auto-renew before expiry. HTTP traffic is redirected to HTTPS.
Cert not issued? Usually a bad CNAME. Run fyra check-domains and read the diagnostic.
Customization
Custom 404 page
Drop a 404.html in your project root and Fyra serves it for not-found URLs instead of the default plain-text response.
Create a 404.html file
project structure
my-site/
├── index.html
├── about.html
├── 404.html ← your custom error page
└── styles/
└── main.css
Write your page
404.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Page not found</title>
</head>
<body>
<h1>404</h1>
<p>Nothing here. Try the <a href="/">home page</a>.</p>
</body>
</html>
Deploy it
terminal
$ fyra push
Scanning my-site...
Packing 25 files (842.3 KB)
Custom 404 page detected. It will be served for not-found URLs.
Uploading... 842.3 KB sent
Done: https://my-site.apps.fyra.sh
No 404.html? Visitors see a plain 404 Not Found text. Optional but recommended.
Customization
Password protection
Add a .auth file to password-protect your site or any part of it. Visitors get a standard browser login prompt; valid credentials are remembered for the session.
Paid feature. Password protection requires a paid plan. Free-tier pushes containing a .auth file are rejected until you upgrade.
Create a .auth file
One username:password per line. Lines starting with # are comments. Passwords may contain :; only the first colon splits.
.auth
# one user:password per line
alice:s3cret-pa55word
bob:hunter2
Place it where you want the lock
The file's location sets its scope. A root .auth protects the whole site; one inside a folder protects that folder and everything under it. The deepest .auth on a path wins.
project structure
my-site/
├── index.html ← public
├── .auth ← protects the whole site
└── admin/
├── .auth ← protects /admin/* with its own logins
└── page.html
Push and verify
terminal
$ fyra push
Done: https://my-site.apps.fyra.sh
$ curl -I https://my-site.apps.fyra.sh/admin/page.html
HTTP/2 401
www-authenticate: Basic realm="my-site.apps.fyra.sh"
Credentials never ship to visitors. Passwords are bcrypt-hashed during deploy, the file itself is blocked from download along with every other dotfile, and protection runs at the CDN edge, so unauthorized requests never touch your origin. An empty or comment-only .auth fails the push on purpose, so a typo can't silently unprotect anything.
Customization
Redirects
Add a .redirects file to send old URLs to new homes. Redirects are served straight from the CDN edge in microseconds with no origin round trip, and they survive origin outages.
Premium feature. Redirects are available on premium plans. Free-tier pushes containing a .redirects file are rejected until you upgrade.
Create a .redirects file
One redirect per line: source target [status]. Status is one of 301, 302, 307, 308 and defaults to 301. Lines starting with # are comments.
.redirects
# source target [status]
/old-page /new-page
/moved /elsewhere 302
/docs/legacy https://docs.example.com/modern
Push and verify
terminal
$ fyra push
Done: https://my-site.apps.fyra.sh
$ curl -I https://my-site.apps.fyra.sh/old-page
HTTP/2 301
location: /new-page
x-cache: RULE
x-cache: RULE means the edge answered directly; your origin was never contacted.
Remove them later
Delete the lines (or the whole file) and push again; the redirect set is fully replaced on every deploy, so nothing lingers.
Good to know. Sources match one exact path (/old does not catch /old/x) and query strings are preserved automatically. A redirect wins over a real file at the same path. The filename must be exactly .redirects: a near-miss like .redirect fails the push with a rename hint instead of silently doing nothing.
Customization
Pretty URLs & SPA hosting
Two switches control how URLs map to files. Both live in the config block of your project's .deploy.yaml, the file fyra create wrote when you made the app.
Edit .deploy.yaml
.deploy.yaml
config:
clean_urls: true
spa_redirect: /index.html
Both keys are optional; set the ones you want and push.
clean_urls: drop the .html
With clean_urls: true, extensionless URLs resolve to their file, and directories resolve to their index page. Link to /about, not /about.html.
url → file
/about → about.html
/blog → blog.html or blog/index.html
/docs/ → docs/index.html
spa_redirect: one shell for every route
For single-page apps (React, Vue, Svelte, and friends), set spa_redirect to your shell page. Any URL that matches no file serves the shell instead of a 404, and your client-side router takes over.
.deploy.yaml
config:
spa_redirect: /index.html
The value must be a site-absolute path such as /index.html or /app.html.
Push
terminal
$ fyra push
Done: https://my-site.apps.fyra.sh
Config changes apply on the next push, per app.
They combine. With both set, an extensionless URL first tries the file (/about → about.html), then the directory form, and only falls back to your SPA shell when nothing matches. That is the usual setup for an SPA with a few real static pages.
Customization
Excluding files from upload
Create a .fyraignore file using .gitignore syntax.
Create a .fyraignore file
.fyraignore
# Dependencies and build output
node_modules/
.cache/
# Private config
.env
.env.local
# Source files not needed at runtime
src/
*.sketch
*.psd
Verify what will be uploaded
fyra push prints the file count and total size on every push; there's no separate dry-run command.
terminal
$ fyra push
Scanning my-site...
Packing 18 files (210.4 KB)
Uploading... 210.4 KB sent
Done: https://my-site.apps.fyra.sh
What's always excluded
always excluded
.git/ version control history
node_modules/ npm / yarn packages
.deploy.yaml fyra app metadata
.fyraignore is often a subset of .gitignore; start by copying and trimming.