What I have for you today is a single-file tool I call Vessel. A .vessel is a file that contains a tool’s entire UI, a Python (FastAPI) backend, and an SQLite database. All the data lives inside this single file.
Currently, I have a Vessel Host that is an installable PWA and opens any .vessel file locally.
The purpose behind this was simple: In my career and everyday life, I create a lot of tools in spreadsheets. Spreadsheets are okay, but they’re not always the most user-friendly from a UI perspective. I’ much rather use web technologies, but it’s not as easy for the everyday-person to use them if they need a real backend and database. So, I ran with the spreadsheet model (zipped file with data and manifest) to create .vessel. And it worked.
How it works: the Python backend runs in the browser with Pyodide. FastAPI is dispatched through a fetch->ASGI bridge, so the UI talks to the backend with no network involved. The SQLite DB travels inside the .vessel. Saving the edited tool (like saving a spreadsheet) writes back to the original file via the File Handling API’s writable handle.
One use case that turned out to matter more than I expected is this is a good format for AI-generated tools. Most AI “artifacts” aren’t great. I’ve tried to rewrite some of my spreadsheet tools to have a better UI, and it just hasn’t worked out. AI is good with web tech, but it’s usually multiple files and not something non-technical people feel comfortable with. But with .vessels, everything is different. They look great, they function great, they’re one file.
Security was a large design constraint since you're running code from files other people hand you (basically the Office-macro issue). What I wanted was that opening a .vessel should be no more dangerous than opening a web page. That rests on a few things. The .vessel runs in a sandboxed iframe inside the Pyodide/WASM sandbox, network egress is default-deny (a .vessel can only reach the https origins it declares in its manifest), and the host never hands its writable file handle to .vessel code. .vessel’s can optionally be Ed25519-signed to show the code behind the tool hasn't changed from the original author.
I have a gallery of 15 example tools (a budget tracker, a SQLite playground, a regex tester, a JWT inspector, and an API workbench that makes its calls from the Python side so there's no CORS wall, among others). There is a SKILL.md file in the repo if you want to try AI-generated .vessels. Lastly, ‘npm i -g vessel-cli’ for sdk tools.
Honest caveats: the full double-click-and-save-in-place experience needs a Chromium-based browser (the File Handling API). Firefox and Safari fall back to open-from-the-app plus save-by-download. The first open downloads the Pyodide runtime, which is cached after that. It's early. This is v0.2.
What I have for you today is a single-file tool I call Vessel. A .vessel is a file that contains a tool’s entire UI, a Python (FastAPI) backend, and an SQLite database. All the data lives inside this single file.
Currently, I have a Vessel Host that is an installable PWA and opens any .vessel file locally.
The purpose behind this was simple: In my career and everyday life, I create a lot of tools in spreadsheets. Spreadsheets are okay, but they’re not always the most user-friendly from a UI perspective. I’ much rather use web technologies, but it’s not as easy for the everyday-person to use them if they need a real backend and database. So, I ran with the spreadsheet model (zipped file with data and manifest) to create .vessel. And it worked.
How it works: the Python backend runs in the browser with Pyodide. FastAPI is dispatched through a fetch->ASGI bridge, so the UI talks to the backend with no network involved. The SQLite DB travels inside the .vessel. Saving the edited tool (like saving a spreadsheet) writes back to the original file via the File Handling API’s writable handle.
One use case that turned out to matter more than I expected is this is a good format for AI-generated tools. Most AI “artifacts” aren’t great. I’ve tried to rewrite some of my spreadsheet tools to have a better UI, and it just hasn’t worked out. AI is good with web tech, but it’s usually multiple files and not something non-technical people feel comfortable with. But with .vessels, everything is different. They look great, they function great, they’re one file.
Security was a large design constraint since you're running code from files other people hand you (basically the Office-macro issue). What I wanted was that opening a .vessel should be no more dangerous than opening a web page. That rests on a few things. The .vessel runs in a sandboxed iframe inside the Pyodide/WASM sandbox, network egress is default-deny (a .vessel can only reach the https origins it declares in its manifest), and the host never hands its writable file handle to .vessel code. .vessel’s can optionally be Ed25519-signed to show the code behind the tool hasn't changed from the original author.
You can try out everything at https://getvessel.dev/
I have a gallery of 15 example tools (a budget tracker, a SQLite playground, a regex tester, a JWT inspector, and an API workbench that makes its calls from the Python side so there's no CORS wall, among others). There is a SKILL.md file in the repo if you want to try AI-generated .vessels. Lastly, ‘npm i -g vessel-cli’ for sdk tools.
Honest caveats: the full double-click-and-save-in-place experience needs a Chromium-based browser (the File Handling API). Firefox and Safari fall back to open-from-the-app plus save-by-download. The first open downloads the Pyodide runtime, which is cached after that. It's early. This is v0.2.
Source (Apache-2.0): https://github.com/apollo-orbit-dev/vessel
I'd love feedback, especially on the security model and the .vessel format.