Windows · Linux · macOS · Edge, Chrome, Firefox

Double-click.
It just runs.

Fenestra is a tiny local server that turns any dist/index.html into a working site in your browser. No terminal, no extension, no custom browser.

~120 KB MIT license no .NET SDK one file, no installer

Any system? Compile it yourself →

The problem

The problem is the origin, not the file

Modern builds use ES modules. Under file:// the browser treats the page as an opaque origin: modules are blocked by CORS, /assets/... resolves to the root of the drive, and service workers do not exist. The file is fine. The origin is not.

file://

What happens when you double-click a build today:

  • Module scripts blocked by CORS
  • Absolute paths point at the drive root
  • No service worker, no manifest, blank page

http://127.0.0.1

What happens when Fenestra serves the same folder:

  • Modules load, exactly like production
  • SPA routes survive a refresh
  • Same tab, same profile, your browser

How it works

Three steps, none of them yours

Fenestra attaches itself to the double-click and decides what the file needs.

01

You open the file

Double-click it, drag the folder onto the executable, or pass a path on the command line.

02

Fenestra decides

It reads the HTML. Needs an HTTP origin? It starts a server on a stable port. Does not? It opens the file directly.

03

Your browser shows it

A normal tab, in your window, with your profile, your extensions and your address bar.

Compatibility

What works, what does not

If the folder works on any static host, it works here. If it needs a build step or a backend, it does not — and Fenestra says so instead of failing silently.

Case Works? Why
dist/ · build/ · out/ Yes Plain HTML, CSS and JS served from the folder.
SPA routes Yes Extensionless paths fall back to index.html, so refresh works.
index.html (single file) Yes Opened directly by Edge through file://, with no server at all.
/src/main.tsx No Source projects need their own dev server to compile.
API · backend No Fenestra serves files. It does not proxy, run services or touch a database.
pages/index.html with ../ No The root is the file's folder, and .. is confined for safety.

Platforms

One idea, three systems

Same job everywhere: turn a folder into localhost and open it in your browser. The packaging changes because each system has its own rules.

Windows .exe

A single ~120 KB executable. No installer, no runtime — .NET Framework 4.8 already ships with Windows.

  • Download Fenestra.exe and run it, or make it the .html handler.

Every release also ships the complete source as zip and tar.gz. Nothing here is closed.

Install

One file. No installer.

Pick the package for your system. Every one of them is a single file — no installer, no runtime.

Windows

The ~120 KB .exe above runs as-is. No installer, no runtime.

The binary is not code-signed yet, so Windows SmartScreen will ask for confirmation once. That is expected for an alpha build.

Linux

On Linux there is a native build: one static binary, no Wine, no runtime. Download fenestra-linux-amd64 from the release and run it with chmod +x.

macOS

On macOS there is no prebuilt binary: Apple notarization costs US$ 99/year. The macos/ folder is a build kit — install Go, run one command.

Build from source

Compile it yourself

Binaries exist for Windows and Linux, and Homebrew covers the macOS CLI. But you can build every one of them from source — and on macOS it is the only way: there is no notarized binary, Apple charges US$ 99/year, and Gatekeeper blocks unsigned downloads.

Release files on GitHub →

A single ~120 KB executable. No installer, no runtime — .NET Framework 4.8 already ships with Windows.

# requires only the csc.exe that ships with Windows
git clone https://github.com/benedetleandro/fenestra.git
cd fenestra
powershell -ExecutionPolicy Bypass -File .\build.ps1

Build with build.ps1 using the csc that ships with Windows.

One static binary, no runtime, for amd64 and arm64.

git clone https://github.com/benedetleandro/fenestra.git
cd fenestra/linux
CGO_ENABLED=0 go build .

Build with CGO_ENABLED=0 go build . inside linux/.

  1. Install Go
    The official installer is signed by Google, so macOS shows no warning. It is the only thing you install.
  2. Get the source
    git clone, or download the ZIP if you do not have git.
  3. Run the build
    The script builds the CLI and Fenestra.app, then re-signs the app after editing the bundle.
  4. Use it from the Finder
    Drag Fenestra.app to /Applications, right-click an index.html, Open with → Fenestra → Always.
# 1. install Go from https://go.dev/dl/
git clone https://github.com/benedetleandro/fenestra.git
cd fenestra/macos
./build.command

No Xcode, no Apple account, no US$ 99. Tested on a real macOS runner in CI (arm64); on Intel the build is native.

Full macOS instructions →

Browser

Pick the browser, once

Fenestra opens a normal tab in the browser you choose. The choice is saved and applies to every double-click from now on.

Fenestra reads the system default browser on every open (the http association), so changing it in Windows is picked up immediately. Nothing is stored unless you pin a browser in settings.

Double-click Fenestra with no file to open this screen again.

# Windows
Fenestra.exe --browser edge

# Linux / macOS
fenestra --browser edge

See what is installed with --browsers.

# Windows
Fenestra.exe --browser chrome

# Linux / macOS
fenestra --browser chrome

See what is installed with --browsers.

# Windows
Fenestra.exe --browser firefox

# Linux / macOS
fenestra --browser firefox

See what is installed with --browsers.

# Windows
Fenestra.exe --browser brave

# Linux / macOS
fenestra --browser brave

See what is installed with --browsers.

# Windows
Fenestra.exe --browser vivaldi

# Linux / macOS
fenestra --browser vivaldi

See what is installed with --browsers.

# Windows
Fenestra.exe --browser opera

# Linux / macOS
fenestra --browser opera

See what is installed with --browsers.

# Windows
Fenestra.exe --browser chromium

# Linux / macOS
fenestra --browser chromium

See what is installed with --browsers.

# macOS only
fenestra --browser safari

Safari is available on macOS only.

Use the system default

With --browser default, the operating system decides. To change what that means:

  • Windows: Settings → Apps → Default apps → choose your browser.
  • macOS: System Settings → Desktop & Dock → Default web browser.
  • Linux: xdg-settings set default-web-browser firefox.desktop

Stored in %LOCALAPPDATA%\Fenestra\browser.txt (Windows), ~/.config/fenestra/browser (Linux) and ~/Library/Application Support/Fenestra/browser (macOS).

Usage

Usage

# open a build
Fenestra.exe "C:\projects\app\dist\index.html"

# open a folder
Fenestra.exe "C:\projects\app\dist"

# force the server, skip detection
Fenestra.exe --serve "C:\path\index.html"

# choose the browser (edge is the default)
Fenestra.exe --browser chrome
Fenestra.exe --browsers

# register / unregister the .html handler
Fenestra.exe --install
Fenestra.exe --uninstall

Under the hood

Small on purpose

One C# file for Windows, and two small Go ports for Linux and macOS. No dependencies, built by compilers you already have — small enough to audit in an afternoon.

ServerHTTP/1.1 on a TcpListener, bound to 127.0.0.1 only. Only loopback Host headers are accepted.
PathsNormalized and confined to the served root. .. , : and ::$DATA are rejected, and so are symlinks that escape it.
PortsFNV-1a hash of the folder maps to a port that is stored and reused, so localStorage survives.
SPA fallbackExtensionless requests return index.html; missing assets still return 404.
Single instanceA second double-click pings the running server and just opens another tab.
LifetimeExits when the Edge it started closes, or after four idle hours.

Security

Local means local

Loopback only, no telemetry, no accounts, no remote code. It serves the folder you opened and nothing else — but every file under that folder is reachable, including dotfiles.

Do not point Fenestra at a directory that contains secrets. The full threat model is in SECURITY.md in the repository.

The name

A window, not a browser

Fenestra is Latin for window: the opening, not the room. That is the whole idea — Fenestra does not render your site, it opens a window onto it and lets your browser look through.

The word survives in Italian finestra, French fenêtre and Portuguese fenestra (the anatomical one), so it reads as "window" to a Romance speaker and as a proper name to everyone else. It is also a quiet joke: a browser is the frame; this is the opening.

FAQ

Questions people actually ask

Does it work with any static site?

Yes. Any folder with an index.html is served as-is. Each folder gets its own stable port, so two apps can be open at the same time without fighting.

Do I need Node.js or any runtime?

No. Fenestra is a single ~120 KB executable built against the .NET Framework that ships with Windows. Nothing to install, nothing to keep updated.

Why does Windows ask me to confirm the .html handler?

Because Windows allows exactly one program per extension and does not let an app claim it silently. That is protection against exactly the kind of software that hijacks file associations.

Does it change my files?

No. It opens them read-only, serves them, and writes nothing to the project. The only state it keeps is a port number per folder, under %LOCALAPPDATA%.

Which browsers does it support?

The system browser is the default. Chrome, Firefox, Brave, Vivaldi, Opera and Chromium are detected automatically — plus Safari on macOS — and --browser edge pins Edge. It opens a normal tab in the browser you already use, so there is no engine to patch and no extra 150 MB.

Is Fenestra a browser?

No. It is a server that opens a tab in your browser. There is no address bar of its own, no tabs, no rendering engine. That is the point.

Will it run on macOS or Linux?

Yes. Linux has static binaries (amd64 and arm64) with a --install flag. macOS has no prebuilt binary: the macos/ kit builds on your machine, with no Apple account and no US$ 99/year notarization.