The weekend project that survives Sunday: one HTML file
The Saturday plan dies on the first npm install. A single self-contained HTML file is the only project shape with no build step, no hosting drama, and no Sunday-night rabbit hole. Here is the playbook, and the tool that writes the file for you in under thirty seconds.
The 48-hour budget problem
A weekend has roughly fifteen usable hours of focus once you remove sleep, food, errands, and the social obligations that materialize on Saturday morning. Most weekend project failures are not failures of imagination; they are failures of accounting. The idea takes ten minutes to describe. The toolchain takes nine hours.
Pick a stack on Friday night and by Sunday morning you have apackage.json, a half-configured ESLint, three deprecated dependencies, and an opinion about Tailwind v4. The actual feature lives in a TODO at the bottom of App.tsx.
A single HTML file is a different deal. The whole project is the file. The build step is saving. The deploy step is dragging the file somewhere. There is exactly one place a bug can live: the file. Friction goes from nine hours to nine seconds.
What a single-file project actually contains
The constraint is that the file works when you double-click it. Open it from file://, attach it to an email, drop it on an SD card, host it from a decade-old Raspberry Pi. If any of those break, you have stopped building a single-file project.
- CSS in a <style> tag. No external stylesheet, no Tailwind build, no PostCSS. Reset and tokens at the top, components below.
- JavaScript in a <script> tag. Vanilla DOM, no framework, no bundler. If you genuinely need React, ship it from a CDN ESM import; otherwise skip it.
- Data as a const literal. JSON you would otherwise fetch lives at the top of the script. Beats CORS, beats hosting, beats authentication.
- State in localStorage or URL hash. Two persistence options that need zero infrastructure. URL hash is free sync between devices.
What that file actually looks like
Here is a complete, real, deployable tip splitter. Eighteen kilobytes. No dependencies. Drag this file into any folder and double-click it.
The tool that writes it for you
Writing single-file HTML by hand is not the hard part of a weekend project; thinking through inline state, accessible markup, a print stylesheet, and a sensible color scheme in fifteen minutes is. mk0r does that part. You type a sentence, mk0r writes the file.
The free tier that emits this kind of file is wired to Claude Haiku. The exact line is in the source you can read right now:src/app/api/chat/model/route.ts, line 5: export const FREE_MODEL = "haiku". That is the model the Quick path serves, and Quick is the path that produces a one-file HTML output.
The output streams. Tokens come back as NDJSON throughreadNDJSON() insrc/app/api/chat/route.ts, which is why you see the file appear word by word in the preview iframe instead of waiting for the closing tag. The page is usually interactive in the iframe before the response finishes, because the browser parses incrementally.
Verifying the output is actually self-contained
The whole point of a single-file weekend project is that it owes nothing to the place it was generated. Two grep commands prove it.
If grep -E 'mk0r|http' on the saved file is empty, there is no analytics, no telemetry, no third-party request, no surprise. If you asked the prompt to include a CDN font you will see exactly that font CDN URL and nothing else. The file does not know where it came from.
That property is what makes the file a real weekend project: you can email it to grandma, drop it on an air-gapped machine, or pin it on IPFS, and it keeps working.
Eight projects that fit in one HTML file
Each of these has been built end to end inside a single file and tested by opening it from the desktop. Pick one with a constraint you actually have, not the one that sounds most impressive.
Tip splitter for awkward dinners
Three inputs, one big output, one URL to text the table. Renders before the waiter swipes the card.
Standing-desk reminder
Page in a tab, browser tab title flashes every 50 minutes with a chime. State lives in localStorage so a refresh does not lose the streak.
RSVP page for a small thing
A static guest list and a mailto: button. No backend, no Eventbrite fee, no email harvested. Send the URL, done.
Kid-safe spelling drill
JSON list of words inline, shuffles per session, reads them aloud with the SpeechSynthesis API. Works on a Chromebook with no install.
Conference badge generator
Form on the left, SVG badge on the right, print-CSS that fits a Brother label printer. The whole tool fits in a Slack pin.
Local-first habit tracker
Seven dots a day, fourteen weeks, JSON in localStorage. Export and import as a base64 string so syncing is just a paste.
Public API dashboard
Pick a free, no-key API (sunrise time, USGS earthquakes, Frankfurter FX). Fetch on load, render with vanilla DOM. One file, one chart.
Wedding countdown for grandma
Big numbers, big font, no chrome. Email the file as a .html attachment and grandma double-clicks it. No App Store review.
From sentence to deployed in five steps
The whole loop, ordered by what kills you if you skip it. The tooling has nothing on this page; the only things you need are a browser tab and a place to drop the file.
Open mk0r in a tab
No signup, no email gate, no install. The home page is the editor.
Type the project in one sentence
'Tip splitter for three people, system fonts only, dark mode by default, no external assets.' Specifics earn you a smaller file.
Watch the file stream in
Tokens land word by word in a preview iframe. By the time the closing </html> writes, the page is already interactive in the preview.
Save as project.html
Right-click the preview, Save As, pick a name. The download is the entire app: open it offline, email it, drop it on a USB stick.
Drag onto Netlify Drop
Five seconds to a public URL. No CLI, no GitHub repo, no DNS. If you wanted a real domain you can use mk0r's publish flow instead.
Where the file goes after Sunday
One thing makes the single-file shape pay off compounding: it travels. The same artifact reaches a public URL, an inbox, and a USB drive without changes. None of those paths needs a build pipeline because there is no build to pipeline.
single file, many destinations
What you keep when the weekend ends
Most projects finished on a Sunday die because they need to be re-deployed somewhere stable on Monday and you cannot remember the command. This project lives wherever you put it. If Netlify sunsets Drop, drag the same file onto Cloudflare Pages. If your account expires, email it to yourself. The file is the project.
That portability has a side effect: you can iterate on the same file for years without a backend, a database, a release process, or an audit. 0 hours of work keeps shipping for as long as you keep the file around. That is unusually durable for software.
Have a weekend idea but not the time to wire it up?
Hop on a fifteen-minute call. Bring the sentence; we will run mk0r live and walk through the file it streams.
Frequently asked questions
What actually counts as a single-file HTML weekend project?
One .html file you can double-click. CSS lives inside a <style> tag, JavaScript lives inside a <script> tag, any data lives in a const at the top of the script. No bundler, no node_modules, no build step. The whole thing fits as an email attachment, a USB stick, a GitHub Gist, a Netlify Drop, or a single line in a S3 bucket. If you have to run npm install before it works, it is not a single-file project.
Why does a single file matter when I could just use a bundler?
Friction kills weekend projects. A bundler adds three things you do not have time for on a Saturday: an install step, a build step, and a hosting story. Each one is a place to get stuck. A single HTML file collapses all three into 'save the file, open the file.' The deployment story is whatever the cheapest static host you have access to is. The shipping story is 'I made this, here is the file.'
Which model does mk0r use for the single-file HTML output?
Claude Haiku. The wiring is in the source: src/app/api/chat/model/route.ts, line 5: 'export const FREE_MODEL = "haiku".' That is the model the free tier serves Quick mode requests with, and Quick mode is the path that emits a single self-contained HTML file. The token stream comes back through readNDJSON in src/app/api/chat/route.ts, which is why you see the file appear word by word in the preview iframe rather than all at once.
Does the generated file phone home to mk0r?
No. The output is plain HTML, plain CSS, plain JavaScript. There is no mk0r runtime, no analytics beacon, no fetch back to our servers. You can verify this yourself: download the file, open it in a text editor, search for 'mk0r' and search for 'http'. You will find nothing beyond fonts or CDN libraries you explicitly asked the prompt to include. If you ask for 'no external fonts, system fonts only, no CDN,' the network tab on first load is empty after the file itself.
Where do I host a single HTML file once I finish it?
Cheapest path on Sunday night: drag the file onto Netlify Drop, get a live URL in roughly five seconds, no account required. Next cheapest: a GitHub Gist with a CSP-friendly raw URL via githack. If you own a domain, drop the file in a Cloudflare R2 bucket with a public alias. If you want a real subdomain, mk0r itself can publish from the in-browser session. None of those needs a build pipeline because there is no build to pipeline.
Can I edit the file after mk0r generates it?
Yes, that is the whole point. The output is real source code in a real .html file, not a binary, not a proprietary format, not a database row. Open it in any editor and change any line. Iterate by feeding the modified file back to mk0r as the next prompt or by hand-editing in your editor. You can also keep iterating in the in-browser session and just re-export when you are happy.
What kinds of weekend ideas fit a single file and what kinds do not?
Fit: calculators, timers, generators, single-page games, data viewers reading a JSON literal, dashboards reading from a public API, kiosks, e-ink homepages, kid-friendly tools, conference badges, RSVP pages, party countdowns, study cards, voting tools that store state in URL hash, tip splitters, recipe scalers, beat tickers, breathing apps. Do not fit: anything that needs a server, a database, multi-user state, secrets you cannot expose in the client, or auth. For those, mk0r has a separate VM mode that boots a full Vite + React + TypeScript project, but that is no longer a single file.
One sentence. One file. Ship by Sunday. No signup required.
Build my weekend project