Back to journal
BUILD LOG

How we ship tiny websites

Our process, tools, and the slightly chaotic system behind shipping 10+ websites. This is the full story, from the first idea scribbled in a notes app to a live site on a custom domain.

A laptop on a desk with the words Good Ideas Ship written across the screen

1. Introduction

Over the past three years, Slop Brains has shipped more than ten websites, tools, and experiments. They range from QR Bench, a practical utility for comparing QR code styles and error correction levels, to aislop.meme, a project that exists for no reason other than the fact that memes are funny and the domain was available.

We are not a company. We are not a startup. We are one person with too many browser tabs, a notes file that never stops growing, and a belief that the internet is better when more people put things on it. Small, weird, useful, unnecessary. It does not matter. What matters is that it exists.

This post is the full build log. Not a motivational thread. Not a "how to build a SaaS in a weekend" guide. This is the actual system we use to go from a random thought to a deployed website, written down so we can remember it ourselves and so anyone who is curious can steal the parts that work for them.

The process has evolved over time. Early projects were messy. Domains bought on impulse, half-built pages abandoned in local folders, ideas that sounded brilliant at 1 AM and looked terrible by morning. What we have now is still messy, but it is a system of messiness. There is a pipeline. There are checklists. There is a folder structure that we mostly follow.

If you have ever bought a domain and done nothing with it, this post is for you. If you have ten half-finished projects on your laptop, this is for you. If you think the internet needs more small websites and fewer login walls, you are already one of us.

What this post covers

  • Where ideas come from and how we filter them
  • The exact tools, stack, and services we use
  • Our project structure and naming conventions
  • How we design without Figma (mostly)
  • The deployment pipeline from local to live
  • How we handle domains, DNS, and HTTPS
  • What we check before calling something "shipped"
  • Mistakes we have made and what we learned
  • Why we keep building

2. The idea pipeline

Ideas come from everywhere. That is both the exciting part and the dangerous part. Without a system, every idea feels urgent. With a system, most ideas reveal themselves as forgettable within a week, and the ones that survive are worth building.

Where ideas come from

Most of our projects started as one of these:

  • A personal annoyance. QR Bench started because we needed to generate a payment QR code and every tool online was either ugly, covered in ads, or required an account. We thought: there should be a clean page where you paste data, choose a style, and download a PNG. So we built it.
  • A domain that suggested a product. We browse domain registrars the way some people browse real estate listings. When we found protocols.page, the name immediately implied what it should be: a clean reference for internet protocols. The domain was the idea.
  • A rabbit hole. slang.fyi started when we tried to explain "delulu" to someone and realized there was no good, clean, searchable dictionary for internet slang. Not Urban Dictionary with its chaos. Something simple and browsable.
  • A joke that escalated. aislop.meme was supposed to be a throwaway experiment. Then people started sharing the memes. Then we added more. Now it is one of our most visited projects.
  • A conversation. Someone says "I wish there was a website that..." and we write it down. Half of those ideas are bad. The other half are the best ones we have.
  • An observation about the internet. archives.fyi came from watching interesting pages disappear. Link rot is real. We wanted a place that preserved the good stuff.

The notes file

Every idea goes into a single plain text file. Not Notion. Not a Kanban board. Not a database. A text file called ideas.txt that lives in our Obsidian vault. Each entry is one line: a name, a description, and sometimes a link to the domain if we already bought it.

The format is intentionally low-friction. If capturing an idea requires opening an app, creating a card, choosing a column, and adding tags, we will not do it. We will forget the idea instead. A text file has zero overhead. Open it, type a line, close it.

At any given time, the file has between 40 and 80 entries. Most of them will never get built. That is fine. The file is not a backlog. It is a compost heap. Ideas decompose, merge, transform. Sometimes two mediocre ideas combine into one good one.

Actual entries from our ideas file

  • tlds.fyi: A browsable directory of every TLD with pricing and registration info
  • status.codes: HTTP status codes explained with examples, like httpstatuses.com but updated
  • keyboardtest.page: Test every key on your keyboard, show which ones are dead
  • fontsample.page: Paste your own text and see it in every system font
  • readme.builders: Generate beautiful READMEs from a form
  • exitinterview.fyi: Anonymous exit interview templates for people leaving jobs

Some of these will get built. Some already have domains. Most will stay in the file forever.

The filter: three questions

When an idea survives a week in the file and we are still thinking about it, we ask three questions:

  1. Can someone use this in under 10 seconds? The best small websites have an immediate, obvious action. You arrive, you understand what it does, you use it. If the idea requires a tutorial or a signup flow, it is probably too complex for the kind of thing we build.
  2. Would we use this ourselves? Not hypothetically. Actually. If we would not open this site at least once a month, it probably is not worth the maintenance cost of keeping it alive.
  3. Is the domain available? This sounds superficial, but a good domain does real work. resign.fyi tells you everything you need to know before you click. If the perfect domain is taken, the idea goes back in the file until we find one that fits.

If an idea passes all three, it moves to the build phase. If it fails one, it stays in the file. If it fails all three, it gets deleted. We are ruthless about deletion. The file is only useful if it is not full of noise.

The impulse buy problem

We need to talk about domains. We have bought too many. At the peak, we owned 47 domains. Forty-seven. Most of them pointed at nothing. The annual renewal cost was genuinely embarrassing.

We have since imposed a rule: do not buy the domain until you have written a one-paragraph description of the homepage. If you cannot describe the first thing a visitor sees and does, the domain is not an idea. It is a receipt.

This rule has saved us hundreds of dollars. We still break it sometimes. But less often.

3. Our stack

We optimize for speed, simplicity, and zero unnecessary complexity. The goal is to get from idea to deployed website as fast as possible, with as few dependencies as possible, and with a codebase that we can understand completely six months later without reading documentation.

The default: static HTML, CSS, and JavaScript

Most Slop Brains projects are static sites. No framework. No build step. No node_modules folder. You open the HTML file in a browser and it works. This is not a philosophical stance against frameworks. It is a practical choice for the kind of things we build.

A typical project structure looks like this:

project-name/
├── index.html          # The entire site (often just one page)
├── styles.css          # All styles, no preprocessor
├── app.js              # All interactivity
├── assets/
│   ├── favicon.svg
│   ├── og-image.png    # Open Graph preview
│   └── ...             # Any images or fonts
└── README.md           # What this is and how to deploy it

That is it. No package.json. No tsconfig.json. No webpack config. No CI pipeline. Just files that a browser can read.

The advantages of this approach are hard to overstate:

  • No build step means instant feedback. Save the file, refresh the browser. There is no compilation, no hot module replacement that sometimes works, no waiting for a dev server to restart.
  • No dependencies means nothing breaks. We have projects from 2024 that work identically to the day they shipped. No dependency has been deprecated. No security advisory has required an urgent patch. Because there are no dependencies.
  • The entire codebase fits in your head. A single HTML file, a single CSS file, a single JS file. You can grep for anything. You can read the entire source in one sitting.
  • Deployment is copying files. Push the folder to Cloudflare Pages, Netlify, Vercel, or any static host. Done. No build command to configure. No environment variables to set.

When we use a framework

Not every project fits the static file model. When a project has hundreds of generated pages (like a dictionary with thousands of entries) or requires shared data across routes, we reach for a static site generator.

Our current choices:

  • Astro for content-heavy sites that benefit from Markdown/MDX and static output. slang.fyi uses Astro because it has thousands of dictionary entries that are generated from data files. The output is still static HTML. Astro just helps us avoid writing thousands of HTML files by hand.
  • Next.js (static export) for projects where we want TypeScript, component composition, and static output. protocols.page uses Next.js in static export mode because we wanted typed data models for protocol definitions and component reuse across protocol detail pages.

The key constraint: both produce static output. We do not use server-side rendering. We do not use API routes. We do not use serverless functions. The browser gets finished HTML, CSS, and JavaScript. The server is a dumb file host.

Decision tree: when to use what

  • 1-5 pages, simple interactivity: Static HTML/CSS/JS. No question.
  • 10+ pages from structured data: Astro with static output.
  • Complex component composition, TypeScript throughout: Next.js static export.
  • Real-time features, user accounts, databases: We do not build these. Not yet.

CSS approach

We write plain CSS. No Tailwind. No Sass. No CSS-in-JS. The reasoning is simple: for a small site with one stylesheet, plain CSS is the fastest to write, the fastest to debug, and the easiest to maintain.

We use CSS custom properties (variables) for the color system and spacing scale. We use clamp() for fluid typography. We use modern layout (Grid and Flexbox) for everything. We do not support any browser that does not support these features, which in 2026 means we support every browser that matters.

Media queries are mobile-first. We typically have breakpoints at 430px, 760px, and 1050px. These are not magic numbers. They are the points where our layouts start to look awkward on real devices.

JavaScript philosophy

JavaScript is for interactivity that HTML cannot handle alone. Modals, search filtering, clipboard operations, form validation beyond what the browser provides. We do not use JS for things that CSS can do (animations, hover states, responsive layout) or things that HTML can do (navigation, links, forms).

We write vanilla JS. No jQuery. No React. No Alpine.js. For the size and complexity of our projects, adding a library would make the code harder to understand, not easier. Our app.js files are typically 200-400 lines. That is small enough to read top-to-bottom and understand completely.

We use modern JS features: const/let, arrow functions, template literals, async/await, optional chaining, querySelectorAll with spread, destructuring. We do not use modules (import/export) for most projects because a single script tag is simpler and there is not enough code to justify module boundaries.

Icons

We use Lucide icons loaded from a CDN. This gives us a consistent icon set across all projects without bundling an icon font. The icons are rendered as inline SVGs, which means they can be styled with CSS (color, size, stroke width) like any other element.

The one downside is that icons require a network request on first load. We mitigate this by ensuring all interactive controls also have text labels, so the page is usable even if the CDN is slow or unavailable.

Fonts

We use Inter for everything. It is an excellent screen font, it is open source (SIL Open Font License), and it has the weight range we need (400, 500, 600, 700). We self-host the WOFF files to avoid a third-party font CDN and use font-display: swap to prevent invisible text during loading.

For code snippets, we use the system monospace stack: ui-monospace, SFMono-Regular, Consolas, monospace. No custom code font. The system defaults look good enough and load instantly.

4. The design process

We do not have a formal design process. We do not create wireframes in Figma before writing code. We do not build design systems with named tokens and documented components. For the kind of small, fast projects we ship, that level of process would slow us down more than it would help.

What we do instead:

Start with the content

Before writing any code, we write the actual content that will appear on the page. Not lorem ipsum. Not placeholder text. The real words. This forces us to think about what the page needs to communicate before thinking about how it looks.

For QR Bench, the content exercise was: "A visitor arrives. They want to generate a QR code. What do they need to see? An input field for the data. Options for size and error correction. A preview. A download button. Done." That content outline became the layout.

For slang.fyi, it was: "A visitor arrives. They want to look up a word. They need a search bar, a list of results, and clear definitions with examples." The design followed the content structure, not the other way around.

Design in the browser

We write HTML first, then CSS. We start with unstyled semantic HTML that contains the real content. Then we add styles progressively: layout, typography, colors, spacing, borders, shadows. At each step, we check the result in the browser at multiple viewport widths.

This approach has a major advantage: we are always looking at the real thing. There is no gap between the mockup and the implementation. There is no "it looked different in Figma" moment. What we see is what ships.

It also means we make design decisions based on how things actually feel to use, not how they look in a static frame. Hover states, focus rings, scroll behavior, transition timing. These things only make sense when you interact with them.

The Slop Brains visual language

Over time, a consistent visual language has emerged across our projects. Not because we designed a system upfront, but because we kept making similar choices and eventually codified them:

  • Dark background. #0d1114 for the page, #12171b for panels and cards. Dark mode is our default (and only mode) because it looks better for the kind of content we publish and reduces eye strain for the late-night browsing sessions that define our audience.
  • Blue accent. #1672ff for interactive elements, links, CTAs. A single accent color keeps the palette simple and makes interactive elements immediately identifiable.
  • Rounded corners everywhere. 12px on buttons and inputs, 16-17px on cards and panels. This gives everything a soft, approachable feel without looking childish.
  • Subtle borders. #242c33 for default borders, slightly lighter on hover. Borders define structure without creating visual noise.
  • Restrained typography. Inter at 15px base, clamp() for headings, negative letter-spacing on large text. No decorative fonts. No display typefaces. Just clean, readable text.
  • Generous spacing. We err on the side of more whitespace. Cramped layouts feel anxious. We want our sites to feel calm and confident.

Responsive design approach

Every project is designed for three breakpoints: narrow phones (≤430px), tablets and small laptops (431-760px), and desktop (761px+). We do not obsess over specific device sizes. We look for the points where the layout breaks and add a media query there.

Our responsive strategy is simple:

  1. Desktop: multi-column grids, spacious padding, full navigation
  2. Tablet: reduce columns, tighten spacing, keep navigation visible
  3. Phone: single column, stacked layout, hamburger menu, larger touch targets

We test on real devices. Not just browser DevTools (though we use those too). An actual iPhone SE, an iPad, a large Android phone. DevTools simulates screen size but not real touch interaction, font rendering, or scroll physics.

Accessibility

We take accessibility seriously, not because we are experts (we are not), but because the basics are easy and make a meaningful difference:

  • Skip to content links on every page
  • Semantic HTML: <header>, <main>, <nav>, <footer>, <article>, <section> with headings
  • ARIA labels on icon buttons and interactive elements that lack visible text
  • Focus visible styles that are obvious: 2px blue outline with 4px offset
  • Keyboard navigation for all interactive elements, including custom dropdowns and modals
  • Reduced motion support: prefers-reduced-motion: reduce disables all animations and transitions
  • Color contrast: all text meets WCAG AA contrast ratios against our dark backgrounds
  • Alt text on all images that convey information

Full WCAG compliance requires manual testing with assistive technologies and expert review. We cannot claim full compliance, but we cover the foundations consistently.

5. Build, ship, repeat

This is where the work happens. An idea has survived the filter. The content is written. The domain is purchased. Now we build the thing.

Day 1: The skeleton

We start by copying a minimal template that contains our standard boilerplate: the HTML head with viewport meta, theme-color, description, favicon link, font preloads, and stylesheet links. We add the header with the brand logo and navigation, the footer with links, and an empty <main> element.

Then we write the HTML for the core feature. For a tool like QR Bench, that means the input form, the output preview area, and the download button. No styling yet. Just semantic HTML that works without CSS or JavaScript.

At this point, we can already use the page. It is ugly, but it functions. You can type in a field, click a button, see a result. This is important: the site should work at every stage of development. CSS makes it look good. JavaScript makes it smooth. But the core functionality should never depend on either.

Day 1-2: Styles

With the HTML structure in place, we add CSS. We start with the layout: overall page structure, grid or flexbox for the main content areas. Then typography: heading sizes, body text, line heights. Then the component styles: buttons, inputs, cards, panels.

We work from outside in: page layout → section layout → component layout → element styling → hover/focus states → animations. Each step builds on the previous one, and at every point the page looks intentional, just not finished.

Colors come from our established palette. We rarely need to choose new colors. The dark background, blue accent, and muted text colors work for almost everything. If a project needs a unique color (like the green accents on ixp.zone), we add one custom property and use it consistently.

Day 2-3: JavaScript

JavaScript is added last, only for things that genuinely need it. Common patterns across our projects:

  • Search and filtering. Real-time search across a list of items with category filters. We do this client-side because our datasets are small (hundreds of items, not thousands).
  • Modal dialogs. Using the native <dialog> element with custom open/close animations. Handles backdrop click, Escape key, and focus trapping.
  • Clipboard operations. Copy to clipboard with a toast notification. Falls back to the deprecated execCommand('copy') for older browsers.
  • Sort and reorder. Client-side sorting of card grids with FLIP-style animations so items smoothly move to their new positions instead of jumping.
  • Local storage. Saving user preferences (like quiz results or subscription intent) without a backend. Always with a clear notice that data stays on their device.
  • Share API. Using the Web Share API on supported devices, with a copy-to-clipboard fallback.

We write the JavaScript in a single file, organized by feature. Global utilities (DOM helpers, toast notifications, clipboard, download) at the top, then feature-specific code (search, modals, quiz logic) below. No modules, no classes, no state management. Just functions that do things.

Day 3-4: Polish

This is the most underrated part. The difference between a project that feels amateur and one that feels professional is entirely in the polish. Specifically:

  • Empty states. What does the search look like when there are no results? What does the page look like before any data is loaded? Every state of the UI needs to be intentional.
  • Error states. What happens when the user enters invalid data? What happens when clipboard access is denied? Every error needs a helpful message, not a silent failure or a console log.
  • Loading states. If anything takes more than 200ms, show feedback. A spinner, a skeleton, a progress bar. Something that tells the user "this is working, not broken."
  • Transitions. Elements should not appear or disappear instantly. A 150-200ms fade or slide makes state changes feel smooth and intentional. But do not overdo it. Transitions should be felt, not noticed.
  • Touch targets. Every interactive element should be at least 44×44px on mobile. Tiny buttons are the enemy of usable mobile interfaces.
  • Keyboard shortcuts. Cmd+K to focus search. Escape to close modals. Tab through interactive elements in a logical order. These small touches make power users happy.

We spend roughly as much time on polish as we do on the initial build. A polished small site beats an unpolished big one every time.

6. Deployment

We deploy everything to Cloudflare Pages. It is free for static sites, it serves files from a global edge network, and it handles HTTPS on custom domains automatically. We have tried Netlify, Vercel, GitHub Pages, and Render. Cloudflare Pages is the one we keep coming back to.

The deployment flow

  1. Push to GitHub. Every project lives in its own repository. We push the final code to the main branch.
  2. Cloudflare Pages picks it up. The project is connected to the GitHub repo. On push, Cloudflare runs the build command (if any) and deploys the output.
  3. Custom domain. We add the custom domain in the Cloudflare Pages dashboard. Cloudflare handles DNS (we use Cloudflare as our DNS provider for all domains) and provisions an SSL certificate.
  4. Verify. We open the live URL, check it on a phone, click through every page, test every interactive element.

For static HTML projects (no build step), the build command is empty and the output directory is / or .. The files are deployed as-is. For Astro or Next.js projects, the build command is npm run build and the output directory is dist or out.

Total time from "git push" to a live, globally distributed website with HTTPS: about 45 seconds.

Domain management

We register domains through a mix of Cloudflare Registrar (best prices for .com, .net, .org), Porkbun (good selection of new TLDs at fair prices), and occasionally Namecheap (when Porkbun does not have the TLD we want).

After registration, we transfer DNS to Cloudflare for every domain. Having all DNS in one place makes management simple and means Cloudflare Pages can provision SSL certificates instantly.

We maintain a simple spreadsheet that lists every domain we own, where it is registered, when it expires, whether it is active (pointing at a deployed project) or parked (no project yet). This prevents surprise renewal charges and helps us decide which domains to let expire.

Performance considerations

Our sites are fast by default because they are small. A typical Slop Brains project has:

  • One HTML file: 8-15 KB
  • One CSS file: 6-12 KB
  • One JS file: 5-15 KB
  • A few images: 50-200 KB total (WebP, compressed)
  • Font files: 60-80 KB (4 weights of Inter, WOFF)

Total page weight: 130-320 KB. Compare that to the average webpage in 2026, which is over 2.5 MB. Our sites load in under a second on any connection, including 3G.

We do not use a performance monitoring tool. We do not need one. When your total page weight is under 300 KB, performance is not a problem you need to solve.

7. The pre-launch checklist

Before we call anything "shipped," we run through a checklist. It is the same for every project. Some items take 10 seconds. Some take 30 minutes. All of them matter.

The full checklist

Content

  • All placeholder text has been replaced with real content
  • Page title and meta description are set and accurate
  • Open Graph image exists and looks good when shared on Twitter/LinkedIn
  • Favicon is set (we use an SVG favicon that adapts to dark/light mode)
  • All images have alt text
  • Copyright year is correct

Functionality

  • Every link works (no 404s, no broken anchors)
  • Every button does something (no dead clicks)
  • Forms validate input and show clear error messages
  • Search returns sensible results (and handles empty queries)
  • Modal dialogs open, close, and handle focus correctly
  • Keyboard navigation works throughout
  • Browser back/forward buttons work as expected

Responsive

  • Tested on a real phone (not just DevTools)
  • No horizontal scrolling at any viewport width
  • Touch targets are at least 44×44px
  • Text is readable without zooming (minimum 14px on mobile)
  • Images do not overflow their containers

Performance

  • Images are compressed (WebP where possible)
  • Fonts are preloaded
  • No unused CSS or JS (easy when you wrote it all by hand)
  • Page loads in under 2 seconds on a simulated slow connection

Deployment

  • HTTPS is working on the custom domain
  • www subdomain redirects to the bare domain (or vice versa)
  • 404 page exists and is helpful
  • The site works with JavaScript disabled (core content is visible)

We do not use an automated testing suite. For a small static site, manual testing takes 10-15 minutes and catches everything a unit test would miss (layout issues, font rendering problems, subtle interaction bugs). If our projects were larger or had more complex logic, we would add tests. For now, eyeballs and a checklist are sufficient.

8. Mistakes we have made

We have made enough mistakes to fill a separate article. Here are the ones that taught us the most.

Mistake 1: Building before thinking

The early projects were built on impulse. We would buy a domain at midnight and start coding immediately. No content outline. No clear goal. Just vibes and enthusiasm. The result was sites that looked okay but did not have a clear purpose. Some of them are still live, and they embarrass us a little.

The fix: Write the homepage content before writing any code. If you cannot explain what the visitor does and why they would come back, the project is not ready to build.

Mistake 2: Overbuilding the first version

protocols.page launched with animated diagrams, interactive protocol visualizations, and a collaborative annotation feature. None of those features mattered. What people actually used was the plain text explanation of each protocol. We spent two weeks building features that nobody wanted.

The fix: Ship the smallest useful thing. If people use it, add features based on what they actually do, not what you imagine they might want.

Mistake 3: Not testing on real phones

We shipped a project that looked perfect in Chrome DevTools' responsive mode but was completely broken on an actual iPhone. The issue: a CSS backdrop-filter that was not supported in the Safari version that most iPhones were running at the time. DevTools does not catch compatibility issues. It only simulates screen size.

The fix: Test on at least one real iOS device and one real Android device before shipping. Not after. Before.

Mistake 4: Ignoring empty states

QR Bench launched without handling the case where the user enters no data and clicks "Generate." The result was a broken QR code image. Embarrassing, and the kind of thing a 30-second test would have caught.

The fix: For every feature, ask: "What happens when the input is empty? What happens when it is invalid? What happens when it is extremely long?" Test all three.

Mistake 5: Caring too much about analytics

We added Plausible analytics to every project and checked the dashboard obsessively. Did page views go up? Where did visitors come from? What was the bounce rate? This did not help us build better projects. It just made us anxious.

The fix: We removed analytics from most projects. If a project is useful, people will use it whether or not we are watching. If it is not useful, no amount of analytics data will make it better. We keep Plausible on a couple of high-traffic projects to understand broad trends, but we do not check it more than once a month.

Mistake 6: Not writing things down

Early projects had no documentation. No README. No comments in the code. No record of why decisions were made. Six months later, we would open the code and have no idea why the search function had a specific debounce timeout or why a particular CSS hack was necessary.

The fix: Every project has a README that explains what it is, how to run it locally, and how to deploy it. Important decisions get a comment in the code. This is not documentation for other people. It is documentation for our future selves.

9. Why we keep building

The honest answer is that we cannot stop. Ideas keep appearing. Domains keep being available. The notes file keeps growing. The internet keeps producing discourse that could be converted into websites.

But there is a more deliberate reason too. The internet in 2026 is dominated by a small number of very large platforms. Most people experience the web through five or six apps. The open web, the one where anyone can put anything on a domain and share it with the world, feels smaller than it used to.

We believe the open web is the most important technology humans have ever built, and we think it gets better every time someone puts something new on it. Not something that requires a login. Not something that lives behind a paywall. Not something that harvests data. Just a website. With a domain. That anyone can visit.

That is what Slop Brains is. A collection of small websites. Some useful, some silly, all real. And we are not stopping.

"The internet is a better place with more small, weird websites."

What's next

We have a handful of projects in various stages of development. Some are tools. Some are references. Some are experiments that might not work. We are not announcing anything specific because we have learned that the best projects are the ones that surprise us too.

If you have read this far, you are probably the kind of person who should be building things for the internet. You do not need permission. You do not need a framework. You do not need a marketing strategy. You need an idea, a domain, and a text editor.

Go build something. Put it on the internet. Tell us about it.

TL;DR for the whole post

  • Keep ideas in a text file. Filter ruthlessly. Build the survivors.
  • Use the simplest stack that works. For most small sites, that is HTML, CSS, and JS.
  • Write the content before writing the code.
  • Design in the browser, not in a design tool.
  • Ship the smallest useful thing. Polish it after people use it.
  • Deploy to a static host with a custom domain. HTTPS. Done.
  • Test on real devices. Check empty states. Handle errors.
  • The internet needs more small, weird websites. Go build one.
BUILD SMALL THINGS

Got a weird, useful idea?

Put it into words. This local demo lets you save a brief to take with you.