Local Test
Works on my machine. On purpose.
A desktop app that serves any folder on your computer at a real
http://localhost address, in one click, with no terminal and
no account. When the folder is software rather than a site, it runs that
instead, and kills the whole process tree when you stop it.
Where to start
If you have never run a server
You do not need to learn anything first
Local Test is a window with a list of folders and a Deploy button. You pick a folder, you press it, and a browser opens on your work. There is no terminal, no config file, no signup, and nothing to break. If you do not have a folder yet, the app can make you one that works.
If python -m http.server is muscle memory
Here is what it actually does
A Node http server bound to 127.0.0.1, with
a Host allowlist, a symlink-resolved path jail, a dotfile and
key-material deny list, Range support, and SSE live reload. Command
projects run in their own process group. Nothing is reported anywhere.
Internals and security posture Honest comparison Server reference
Interactive, in your browser
Rehearse the deploy before you download
A hand-built replica of the Local Test window: not a video, not a screenshot, and not the real app. Press Deploy, change the port, open the Activity tab. It responds the way the app does on your machine, including the request log.
portfolio
LIVE~/Sites/portfolio
Local deployment
Not deployed. Hit Deploy to serve this folder at http://localhost:8001.
Your site is live at
Activity
- Deployed, serving on port 8001
- GET / → 200 (3ms)
- GET /styles.css → 200 (0.8ms)
Live at http://localhost:8001/, the Activity tab has the request log.
A replica. Nothing is served, and no button here reaches your machine.
What it does
Serves a folder
Deploy starts a static server that follows the rules a static host follows: index.html at directory roots, your own 404.html, a redirect when a directory URL is missing its slash, a clean listing when a folder has no index page, correct content types, and Range requests so video and audio seek properly.
Live reload is on by default, save a file and the open page refreshes itself. Per project you can turn listings off, switch on SPA fallback for client-side routers, or name the folder to serve; left on auto, Deploy serves the project root, or finds the built site in _site, dist, build, public, or out when the root has no index page. A port that is already taken gives a plain error and a one-click move to the next free one.
Runs software, too
When the folder is a program rather than a site, Deploy becomes Run. Adding a folder with a package.json start or dev script, a Cargo.toml, a go.mod, or a Python entry point prefills the command; you can write any command you like instead.
Its output streams into the Activity feed line by line, a KEY=value block sets environment variables for the run, and Stop kills the whole process tree rather than leaving children behind.
Files, and an editor
Every project opens on four tabs, Overview, Files, Activity, Settings. Files browses the project and renders its README the way a code host does, and you can create, rename, and delete files there (deletes go to the Trash).
Any text file opens in an editor with edit, split, and preview modes: a Markdown toolbar, Cmd/Ctrl+B, I and K, find and replace, lists that continue themselves, word and reading-time counts, and an auto-save switch that pairs with live reload so the browser keeps up as you type. Inserting an image copies it into the project for you. Cmd/Ctrl+F searches every text file in the project and drops you into the editor at the line you pick.
Git and GitHub, one button deep
The project’s Settings tab shows the branch, the changed files, ahead and behind counts, and the last commit. One button commits everything with your message; another pushes, using the git credentials you already have.
Link a project to an owner/name repository and Sync now clones it or fast-forward-pulls it, optionally before every deploy. App settings can add a repository straight from GitHub into a clone folder you choose.
A window to work in
Cmd/Ctrl+K opens a command palette over everything, and a cheat sheet lists the rest of the shortcuts. Drag the sidebar to reorder projects, and search it when the list gets long. Seven starter templates scaffold something into an empty folder, six of them deployable and one a Minecraft plugin for IntelliJ.
The menu-bar icon starts and stops projects without opening the window; on macOS the Dock badge counts what is live. Preview opens the running site at phone, tablet, or desktop size. Activity logs every request with the time it took beside a running uptime, and exports to a file. Your project list and settings export and import, for moving to another machine.
Thirteen themes and a font size. Open a project in any of sixteen editors, the whole JetBrains family included, or point it at one of your own. The button carries a menu for switching, and a project can have its own.
Local by default
Servers bind to 127.0.0.1, so a deployed site is visible to your machine and nothing else, until you turn on LAN sharing for the day you want your phone to see it. Every request is jailed to the project folder with symlinks resolved, so a cloned repository can’t serve something from elsewhere on your disk.
There is no account, no analytics, and no telemetry, nothing about you or your projects is collected. What does use the network is short and deliberate: the update check on launch, which asks whether a newer version exists (switchable off), the download when you choose to install an update, and git clone, pull, and push when you press those buttons.
Arrived in v1.34.0
It sets up Minecraft servers, too
The same window and the same Stop button. Choose a flavour, a Minecraft version, a folder, and how much memory the server may have. Local Test fetches or builds the server software, writes the two files that have to sit beside it, and starts it on the Java that version actually needs. Java Edition, on your own machine, hosted nowhere, with no panel to rent and nobody to pay monthly.
| Flavour | How it arrives | Checked against | Plugins |
|---|---|---|---|
| Paper | Download from PaperMC | SHA-256 | Yes |
| Purpur | Download from PurpurMC | MD-5 | Yes |
| Vanilla | Download from Mojang | SHA-1 | No |
| Spigot | Compiled on your machine | None published | Yes |
| CraftBukkit | Compiled on your machine | None published | Yes |
Paper is the sensible default: it runs Spigot and Bukkit plugins unchanged, it is faster once there are players in the world, and it is a download, so it is ready in the time it takes to fetch a file.
Why two of them take twenty minutes
Spigot and CraftBukkit may not lawfully be handed out as
files, by this app or by anybody: they contain decompiled
Mojang code. What SpigotMC publish instead is BuildTools, a jar that
fetches the pieces and compiles the server where it will be used, which
is the only lawful route to one. So picking either of those downloads
a compiler rather than a server, and on an ordinary machine that is
five to twenty minutes and needs git
installed.
Local Test says that before it starts, and puts the compiler’s own output in the Activity tab while it runs. Twenty silent minutes looks exactly like an app that has hung, and the reasonable thing to do to an app that has hung throws the build away.
What is checked before it runs
Every address is checked against a list of hosts compiled into the app
before a request is made, so a manifest fetched from the internet cannot
point the download somewhere else. The hosts are
mojang.com for the vanilla jar and the version list,
papermc.io for Paper, and hub.spigotmc.org for
BuildTools. Where the publisher publishes a checksum, the bytes are
checked against it: a SHA‑1 from Mojang, a SHA‑256 per build
from PaperMC.
BuildTools is the one download with nothing to check it against, and the app says so rather than implying a verification that is not happening: SpigotMC publish no checksum for BuildTools, so this download is protected by HTTPS and the pinned host and nothing further.
The EULA is yours to accept
Mojang require their agreement to be accepted before any server will
start, and that agreement is between you and Mojang. It is not this
app’s to sign. Local Test writes the eula.txt
that has to sit beside the server with the line set to
eula=false, and it will not write true on your
behalf however much more convenient that would be.
It asks once, with Mojang’s own address in the question, aka.ms/MinecraftEULA, and then writes what you chose. Saying no is a correct outcome, not a fault.
The address goes into Minecraft, not a browser
This is the one part of Local Test that is not HTTP. A Minecraft
server speaks its own protocol over TCP, so there is no page to open and
no link to click, and the app does not pretend otherwise. What it shows
you is what you paste into Minecraft’s own Add
Server box: localhost from this machine, or the
machine’s address on your network for everybody else in the house.
Port 25565 is the default, so the port can be left off when adding the server in Minecraft. Any other port has to be typed on the end, and the app says which one it is.
Three more things it does, because each one is a bad afternoon otherwise. It reads which Java the version needs from Mojang’s own manifest and checks the machine before the download, rather than letting you meet a stack trace about class file versions. It refuses to install on top of a world that is already there. And it suggests half the machine’s memory, never less than 1 GB and never more than 8 GB, because most of the machine is the wrong answer when the operating system still needs some.
For the sceptical
What is actually running
Deploy starts a server in Local Test’s main process. It is Node’s own
http module, about 600 lines, with no framework underneath it and
no runtime dependencies in the app at all. This is the behaviour you get,
stated precisely enough to argue with.
The static server
- Resolution order
index.htmlthenindex.htmat any directory root. A directory URL without a trailing slash gets a301to the slashed form, each segment re-encoded. With no index page, either a generated listing or your own404.html, depending on the per-project listings switch.- Serve root
- The project root, unless you name a subfolder. Left on auto, when the root has no index page it looks for one in
_site,dist,build,public,out, in that order. It does not run your build. - Methods
GETandHEAD. Anything else is405with anAllowheader. There is no upload path, because there is no other verb.- Range requests
- Full
bytes=support including suffix ranges, answering206withContent-Range, or416when the start is past the end. Video and audio scrub correctly. - Response headers
- Every file and error response carries
Cache-Control: no-cacheandX-Content-Type-Options: nosniff; redirects and the reload stream carry the first of those. Files addContent-Length,Last-Modified, andAccept-Ranges. Content types come from a fixed table; an unknown extension isapplication/octet-stream, never guessed from the bytes. - Live reload
- A recursive
fs.watchon the project, debounced 150 ms, broadcasting over Server-Sent Events at/__localtest/reload. The client is oneEventSourceinjected before</body>of HTML responses only, so your files on disk are never touched. Changes under.git,node_modules, and.DS_Storeare ignored. Where recursive watching is unavailable, serving still works and only the reload is missing. - SPA fallback
- Off by default. On, a miss with no file extension serves
index.htmlat200, so client-side routers get their deep links. Requests that do have an extension still 404, so a missing asset stays a missing asset. - Resource ceilings
- 256 concurrent connections, 24 live-reload subscribers, a 20 s headers timeout and a 120 s request timeout. Stop severs open sockets so the port is free immediately rather than after keep-alive drains.
Security posture
- Binding
127.0.0.1. Another machine on your network cannot reach a deployed site at all, because nothing is listening on an address it can route to. LAN sharing is a separate, off-by-default setting that binds0.0.0.0instead, and turns directory listings off unless you explicitly ask for them.- Host header allowlist
- A request whose
Hostis not a name this server is genuinely reachable under gets403. Without that, any website you visit could point a domain it controls at127.0.0.1and read your projects out of your own browser. This is DNS rebinding, and it is the class of bug most local dev servers still have. - Path jail
- Every read passes one function. It rejects paths that leave the root lexically, then
realpaths the target and confirms containment again, so a symlink cannot walk out. It opens the file once and re-asserts containment on what the handle points at, which closes the window between the check and the read. - Jailed fallbacks
- The directory index, the custom
404.html, the SPA shell, and a named serve folder all go through the same function. A symlinked404.htmlwas a real hole; it is now a test. - Deny list
- Dotfiles at any depth, which covers
.envand.git, plusnode_modulesand obvious key material (id_rsa,*.pem,*.key,*.p12,*.pfx)..well-knownis the single exception. A denied path answers404, not403, so the refusal does not confirm the file exists. - Update channel
- HTTPS only, except loopback for the test harness. A redirect may not drop TLS or change host. The published SHA-256 is required and verified before anything is installed: no checksum means no install, rather than a silent fall-through.
- Provenance
- Each release publishes the installers, a source archive, and
SHA256SUMS.txt. Because the builds are unsigned, that checksum is the thing worth checking.shasum -a 256 -cdoes it in one command on macOS and Linux; Windows has noshasum, so the check there isGet-FileHash, and the download section prints the exact line for each. - On the wire
- No account, no analytics, no telemetry, no crash reporting, no first-run ping. Three things reach the network and all three are yours: the update check (switchable off), an update you chose to install, and git clone, pull, and push when you press those buttons.
Running software
- Launch
- Your command runs through the platform shell with the project folder as its working directory, inheriting the environment plus the project’s own
KEY=valueblock. Adding a folder with apackage.jsonstart or dev script, aCargo.toml, ago.mod, or a Python entry point prefills a command you are free to replace. - Process tree
- On macOS and Linux the child gets its own process group, and Stop signals the group, not the shell:
SIGTERMfirst, thenSIGKILLthree seconds later if it is still there. On Windows it istaskkill /T /F. This is why a stopped project does not leave a dev server holding the port. - Output
- stdout and stderr are read line by line into the Activity feed with ANSI escapes stripped, lines capped at 500 characters and an unterminated buffer flushed past 4 KB, so a program that never emits a newline cannot grow the window without limit.
- Exit
- An unexpected exit is reported with its code or signal and the project returns to stopped. A crash on your side is never a crash on the app’s side.
How it is verified
- Test suites
- More than 10,650 checks across sixty-one plain-Node suites, with no test framework underneath them: the static server, the process runner, the update engine, the Markdown engine, theme contrast, the organizer, the templates, GitHub sync, the Minecraft setup, the editor and its highlighting, the secrets vault, and the assistant. They run without Electron, so the server engine can be exercised on its own. One more boots the real app windowless and drives it end to end.
- Security regressions
- The traversal, symlink-escape, symlinked-index, symlinked-404, dotfile and DNS-rebinding cases are each a named assertion. They exist because an external audit found them live in 1.8.0, which is what 1.9.0 fixed.
- End to end
- A second suite boots the real app windowless and runs a deploy, a software run, a GitHub clone, a Markdown edit and save, a project search, and auto-save.
- Contrast
- Every one of the ten in-app themes is asserted against WCAG AA contrast by a test, so a theme cannot ship unreadable.
- Dependencies
- None at runtime. The whole shipped app is Electron plus first-party code, so the supply chain you inherit is Electron’s and nothing else.
Longer form, setting by setting, in the server reference and privacy and network sections of the docs. Where this page and the app disagree, the app is right and this page is a bug.
How it works
- 1
Add a folder
Any folder, a class project, a portfolio, a prototype. Deploying it only ever reads; nothing is written unless you edit a file yourself.
- 2
Deploy
Or Run, if the folder is software. A port that is already taken gives a plain error and a one-click move to the next free one.
- 3
Open it
Your browser opens at
http://localhost:8000. Edit the files; live reload refreshes the page as you save.
What it is actually like
Seven of the screens you will spend time in. Click any one to look closer.
Thirteen themes
The same screen, ten times, because the only thing that changes between these is the colour and the typeface. All ten ship with the app, alongside a font size, and every one has been checked against WCAG AA contrast by a test rather than by eye. Two of them are pocket consoles. Click any one to look closer.
Default follows whatever your system is set to, which is why its capture is dark here.
Why not just…
Against python -m http.server, npx serve and friends, and
against pushing to a hosted static site. The bottom group is where
Local Test is the wrong tool, which is the half of a comparison table
that is usually missing.
| Task | Local Test | Terminal servers | A hosted static site |
|---|---|---|---|
| Where it is the better option | |||
| Getting a site up | one click | flags and ports | push to a repo first |
| Several projects at once | a list of ports | a terminal tab each | a deploy each |
| Who can reach it | this machine only | often 0.0.0.0 | the whole internet |
| DNS rebinding defence | Host allowlist | usually none | not applicable |
| Symlink escape | jailed, with tests | varies by tool | not applicable |
Dotfiles and .env | refused as 404 | often served | usually excluded |
| Live reload | built in | extra tooling | no |
| Runs your software | built in | separate tools | no |
| Stopping cleanly | group, then SIGKILL | orphans possible | not applicable |
| Show it on your phone | one switch | IP juggling | public URL |
| Where it is not | |||
| Running your build | serves output only | no | yes, on push |
| HTTPS and certificates | no | with mkcert | yes, automatic |
| A URL to send a client | no | with a tunnel | yes |
| Scripting and CI | no, it is a GUI | yes | yes |
| Proxying an API | no | some tools | redirects or functions |
| Signed binary | no, checksums instead | via your package manager | not applicable |
| Linux | untested | yes | not applicable |
All three are good tools, and two of them are free in a way this one only partly is. Local Test is for the moments you want the first column, and a terminal is still the right answer for the last seven rows.
What it deliberately isn’t
The first three are what people are usually asking when they ask what this is, and the answer to all three is no. Most of the rest is scope that was decided against. The last two are simply not done yet.
- Not a host. Nothing you deploy is uploaded anywhere, because there is nowhere for it to go. Your files stay in their folder on your disk and are served from there by a server running inside the app. Quit the app and the site stops existing.
- Not a tunnel. There is no ngrok-style relay, no forwarding service, no public URL, and the app will not open a port on your router or touch your firewall beyond the prompt the operating system raises itself. LAN sharing reaches other devices on your own Wi‑Fi and stops at the edge of it.
- Not a way to put a site on the internet. “Deploy” here means localhost, and that is the whole meaning. If what you need is a link to send a client, you need a host, and this is the wrong tool: use one of the many good ones and come back here for the part before that.
- No build pipelines. Files are served as they are, no Jekyll, Vite, or webpack. Run your own build; Deploy will serve
_site,dist,build,public, oroutwhen it finds one, or the serve folder you name. - No HTTPS, no custom domains, no proxying. It is a development server on
http://localhost. - No accounts, no analytics, no telemetry. Nothing about you or your projects is collected or sent anywhere.
- Not a full IDE. The editor is a real code editor now, with eighteen languages highlighted, errors reported as you type, formatting, tabs, and find and replace across a project. What it does not have is a language server, a debugger, refactoring, or extensions, and it is not trying to. Your real editor is one button away.
- Not a complete git client. History, the diff before you commit, staging by file, discard, restore a file from an earlier commit, branches, pull and push. No merging, no conflict resolution, no rebasing, no remote management. When git gets interesting, open a terminal, which is also one button away.
- Not a Minecraft host. The Minecraft servers it installs run on your machine, for you and for whoever is on your network. Friends on the other side of the internet cannot reach one unless you arrange that yourself, and Local Test does not arrange it for you.
- Not code-signed. An Apple Developer ID and a Windows certificate are both paid, yearly, and this project has neither, which is why a downloaded macOS copy needs one right-click → Open, and why an update swaps itself in on relaunch instead of quietly in the background.
- Not yet proven on Windows or Linux. The Windows paths, installer, uninstaller, and process handling are written, but nothing has been run on real Windows hardware, everything so far has been exercised on macOS. Linux should work and has not been tried.
Questions people actually ask
What is “localhost”, actually?
It’s the address your computer uses to talk to itself. http://localhost:8000 means “this machine, channel 8000.” It looks and behaves like a real website in your browser, because it is one, it just lives entirely on your computer.
Does anything leave my computer?
Your files don’t. A deployed project is served by a server bound to 127.0.0.1, which only your own machine can reach, and there is no account, no analytics, and no telemetry, nothing about you or your projects is collected.
Three things do use the network, and all three are things you asked for: on launch the app asks whether a newer version exists (a switch in Settings turns that off); choosing Install downloads that release; and git clone, pull, and push run when you press those buttons. The LAN switch is the only setting that widens who can see a deployed site, and only to devices on your own Wi‑Fi.
Do I need to know how to code?
No. If you have a folder with an index.html in it (from a class, a template, an export) you can use Local Test. If you don’t have one, Cmd/Ctrl+N builds a starter project (blank page, landing page, docs site, single-page app, Node server, portfolio, Spigot plugin). The first six deploy immediately. The last one is different: it is a Minecraft plugin you build in IntelliJ, so there is nothing in it to deploy. There’s a tutorial built into the app that assumes nothing.
Does it work on Windows?
The code is written for it: Windows paths throughout, an NSIS installer and uninstaller, process-tree kill through taskkill /T /F, and the Windows shell behind the editor and terminal buttons. The installer is built and published, and it is on the download button above.
What has not happened is a validation pass on real Windows hardware. Development and testing so far have been on macOS, so treat the Windows build as supported and unproven, and a bug report from a Windows machine is the single most useful thing anyone could send. One known quirk: turning on LAN sharing may raise the Windows firewall prompt on the first deploy, which is expected.
Will it change the files in my folder?
Serving only reads. Everything that writes is something you pressed: saving in the editor (or leaving auto-save on), inserting an image, which copies the file into the project, renaming a file, deleting one, which moves it to the Trash, scaffolding a template into an empty folder, and git commit, push, or a sync that pulls, including the pull-before-deploy setting, if you turned that on for a linked repository.
Does it update itself?
It checks. On launch it reads the public releases feed and stays quiet unless something newer exists; you can turn that check off in Settings, or run it by hand from the version badge. If you choose to install, it downloads the release and (on macOS) swaps the app in place and reopens it; on Windows it hands off to the installer. Because the app isn’t code-signed, that swap happens visibly on relaunch rather than silently in the background.
Why won’t macOS open the download?
Because it isn’t signed with an Apple Developer ID. That’s a paid yearly membership, and this is a free project, so the first launch of a downloaded copy is right-click (or Control-click) → Open, then Open again in the dialog. Once, and it opens normally after that. A copy you build from source never shows it at all.
My site has a build step, can it still serve it?
Local Test serves files exactly as they are; it doesn’t run your build. Run it the way you normally do, and Deploy will find the result: when the project root has no index page, it serves _site, dist, build, public, or out, whichever has one. You can also name the folder yourself in the project’s Settings tab.
Can I look at it on my phone?
Yes, with a deliberate switch. LAN sharing is off by default; turning it on in Settings binds new deploys to your network interface as well, and the project shows a second address like http://192.168.1.20:8000 that devices on the same Wi‑Fi can open. If you only want to check how it looks at that size, the Preview buttons open the live site in a phone-, tablet-, or desktop-sized window without any of that.
What does it cost?
Nothing. There is no trial, no account, no card, and no telemetry, and every feature described on this page is in the download. There is no limit on how many projects you keep, either: there was one, and it is off. What it costs says the whole of it in six lines.
How is this different from python -m http.server?
For one folder, once, it mostly is not, and if that command is already in your shell history it is a fine answer. The differences show up in three places.
Defaults. Python’s server has no Host check, so any web page you have open can point a domain it controls at your port and read the directory. It serves dotfiles, so a .env or a .git/config in the folder is a URL away. It follows symlinks out of the tree. Local Test refuses all three, and has a named test for each.
Several at once. Six projects is six terminal tabs you have to remember the ports of, or one list with a state dot beside each name.
Stopping. Ctrl+C in the wrong tab leaves a dev server holding a port. Stop signals the process group and follows up with SIGKILL.
What you give up is scriptability. Local Test is a GUI, so it does not belong in a Makefile or a CI job, and a terminal server still does.
Can I read the source before I run it?
Yes. Every release publishes a source archive next to the installers, with its SHA-256 in SHA256SUMS.txt like everything else. The static server is one file of plain Node with no framework under it, and the test suites are in the archive too, so you can run them yourself.
Why should I trust an unsigned binary?
You should not trust it because it asks you to. Signing proves an identity paid for a certificate; it does not prove the code is good, and its absence here means one thing only, that a yearly fee has not been paid for a free app.
What is available instead is checkable. Every artifact has a published SHA-256, so you can confirm the file you downloaded is the file that was built, and the source archive lets you read what it does first. The app applies the same rule to itself: an update with no published checksum is refused rather than installed.
Does it work with Vite, Next, Rails, or my framework’s dev server?
Yes, as a command project rather than a static one. Set the command to whatever you already run (npm run dev, bin/rails s, cargo run) and Deploy becomes Run: your dev server does the serving on its own port, and Local Test is the launcher, the log, and a Stop button that takes the whole process tree with it.
The static server is for output, not for sources. Once your build has produced dist or _site, deploying the project statically serves that, which is a closer rehearsal of production than a dev server is.
What happens to my projects if I stop using it?
Nothing, because there is nothing to get out. Your projects are folders on your disk that the app remembers the paths of; it does not import, copy, or wrap them, and uninstalling never touches them. The project list itself is a config.json in your app-data folder, which the app can export and import, and which you can read in any text editor.
What it costs
Nothing, in the plainest sense of the word. There is no account to make, no card to enter, no trial clock counting down, and no upgrade prompt anywhere in the app. You download it and it works.
- No account. Nothing to sign up for, nothing to sign in to. The app has no idea who you are, and neither does this site.
- No card, and no checkout. There is nowhere on this site or in the app to enter payment details, because there is nothing to buy.
- No limit on projects. There used to be one: the free tier kept five saved projects, and a paid tier lifted it. That paid tier is not on sale, and a limit whose only way past is something nobody can buy is a wall with no door in it, so the limit is off for everybody and the app has stopped counting.
- Every feature, on the one download. Deploying, running software, the editor, project search, git, the repository browser, the Minecraft installer, network sharing, all ten themes, backups and updates. Nothing on this page is held back for a tier.
- AI mode spends your money, not through us. It runs on your own provider key, billed by that provider to your own account, and Local Test takes no cut and adds no markup. Ollama on your own machine needs no account and no key at all, and sends nothing anywhere.
- Nothing is collected and nothing is sold. No analytics, no telemetry, no profile. There is no second way this is being paid for.
That is a description of today rather than a promise about next year. The licence permits paid work on as many of your own machines as you use; what it does not permit is redistributing or selling it, which is what leaves the door open to charging for it one day. If that ever happens it will happen in a release, and every release is written down in the changelog.
Get Local Test
Free, and it needs no account, no card, and no signup. Nothing about you is collected, and there is no limit on how many projects you keep. What it costs, in full.
Your computer will warn you the first time
Neither build is code-signed: an Apple Developer ID and a Windows certificate are both paid yearly memberships, and this app is free. So macOS refuses a normal double-click on a downloaded copy, and Windows SmartScreen stops the installer. Both warnings mean “nobody paid to put their name on this”, which is true, and neither means anything was found wrong with the file.
macOS. Right-click (or Control-click) the app and choose Open, then Open in the dialog. Once, then it opens normally forever after. Windows. Click More info on the SmartScreen box, then Run anyway.
What replaces a signature here is something you can check yourself: one command tells you whether the file you received is byte-for-byte the file that was published.
Downloads are prepared per release. If a button is greyed out that file is not on the server right now. Each button carries its own file size once the manifest has loaded.
The macOS and Windows builds are released separately, so one can be a version behind the other. Each button says which version it is whenever they differ, and the changelog says what is in each.
Check the download is the file we published
The app is not signed by Apple or Microsoft, so your computer cannot
vouch for it. You can still confirm the file you got is byte-for-byte
the one published here. Copy the line for your system, paste it into a
terminal, and it answers in one word. If the answer is not
OK, delete the file and do not open it.
shasum -a 256 ~/Downloads/<file>
Get-FileHash "$HOME\Downloads\<file>" -Algorithm SHA256
The macOS line is for Terminal, and works the same on Linux. The Windows line is for PowerShell, which is what the Start menu means by “Terminal” on Windows 11 and by “Windows PowerShell” on Windows 10. Both assume the file is in your Downloads folder; if you saved it somewhere else, change the path.
- macOS installer
- not published yet
- Windows installer
- Source archive
All checksums are also listed in
SHA256SUMS.txt. On macOS and
Linux, shasum -a 256 -c SHA256SUMS.txt checks the lot in
one step, and reports the files in it you did not download as missing
rather than as wrong. Windows has no shasum at all, so
there the line above is the check, one file at a time. Either way the
app verifies this same checksum itself before installing an update, and
refuses a build whose checksum the manifest does not publish.