saved
offline
can't save

Hyperclay is ready.

Every HTML file is a creative application.

Hello to the curious explorers of the web,

We all know an HTML file can be anything:

  • A video editor
  • A spreadsheet
  • A game

But I've always been concerned with the lack of native tools for editing HTML files locally. Where is the Photoshop, Microsoft Excel, and Final Cut Pro of HTML files.

Hyperclay

Hyperclay turns HTML files into malleable artifacts.

Now we can build UIs on top of them with only frontend code.

Every HTML file is a creative application.

The launch

Hyperclay is ready.

Three years, two months, and 7 days ago I wrote a 20-line Node.js script to auto-save an HTML file.

Now I'm writing this email inside a malleable HTML file on my local computer and using the "Hyperclay Local" app that runs on my desktop to instantly sync this file to the web, where it lives at Launch Plan.


What's next

Over the following weeks you'll get 3 emails:

Email Output
Planning Canvas example app Build and deploy in ~4 min
HyperclayJS Missing DOM primitives library
Invitation Beta account signup invitation

Seats will be limited — I want to support each user individually and make sure they find success. If you miss the window, don't worry. General signups will open within a few months.

Beta expectations: You will be the first to try a new way to make software. It will be really cool, I promise. But there will be lots of bugs, I also promise. Bug me about the bugs endlessly, so I can fix all of them and make everyone really happy.


Want to read about how my opinion of software development has changed over the past 5+ years of working on Hyperclay and its predecessors?

Let's hack the web platform and make it better for everyone,

— David

@panphora

P.S. If you followed my earlier experiment into flattening the software stack, Remake the Web, you are receiving this email because Hyperclay is an evolution of that work.

Software is user action

There are two places to get stuck in software development.

The first is building something in your head. Beginners often get stuck here. You dream up a perfect theoretical system, but it's too big to squeeze through the toothpaste tube of your actual abilities.

The second is building something complete. Experienced programmers often get stuck here. You build a system, but your vision for it never quite matches the elegance of what you imagined. You're always just one big feature or one big refactor away from perfection. Your project grows in its ambitions, day by day, until you're crushed under its weight.

The secret is to realize that the unit of work in software development is not specs, designs, or plans of any kind. It's working software.

Just as a painting is composed of paint, software is composed of motion.

In software development, the paint is your users' brushstrokes

A user moves a card, presses a button, turns a dial, and something happens on the screen. That "something happens" is the atom. You cannot see it clearly before you build it, and you cannot build it correctly before someone uses it.

There's a temptation, especially in the age of AI, to believe a complete system is possible without using and refining each part before you build on top of it. AI can generate UI, endpoints, and modules quickly. It can make a system look complete before it has earned any right to exist.

But a document-editing app is not "a WYSIWYG editor plus an API endpoint." It's everything in between.

  • Is the text Markdown or rich text?
  • Is the focus of the UI information density or readable typography?
  • Do you allow every type of document or are you focused on one use case?

Those decisions matter at every level of the user experience. They are not garnish. They determine whether each feature is discoverable, understandable, and trustworthy. And the best way to make sure they are is to grow a system organically, piece by piece, watching how they're used.

The brushstroke is the flow of using the feature. You can't see the brushstroke before someone uses it.

Here's the point where I'm getting stuck right now: AI helps you build instead of over-planning. That's real. But on the flip side, it can push you into the false trap of thinking your project's complete too early. You end up with a feature-packed, self-consistent, operational system that no one uses.

People don't understand how to use it, so features remain undiscovered. Or features are discovered and they break in weird ways as soon as they touch real workflows.

But the above is solvable with feedback. The worst part about working alongside AI is that once your users report an issue, it's much harder to adapt and change direction. There's so much of the system that AI has built that you don't understand. You can't modify it confidently, so it can't adapt. And software is meant to move, grow, and adapt.

I don't think the solution is "don't use AI." It's "use AI for one feature at a time, and have someone use it before you build on top of it."

Here's how I do it in practice:

  1. Pick a small part of a project I can share
  2. Set a timer (60–120 minutes) and finish with something that runs
  3. Make "shareable" part of the definition of done (a URL, a file, a demo video)
  4. Show one person and see how they experience it

A few rules I keep coming back to:

  • You can't build products in the dark. You need to use it and ideally get someone else to use it.
  • You can't build for everyone and every use case.
  • A feature-packed system doesn't matter on its own. It needs to grow with the market, grow with its users, and adapt to the ecosystem it's in.
  • The paint is usable prototypes, not API endpoints or designs.

When software is allowed to grow this way, it becomes real. It earns its completeness by moving and adapting the way people expect it to move and adapt to them. That's what "complete" should mean. Let users do one thing at a time, and do it well. Each brushstroke should flow naturally from the one that came before it.

HyperclayJS.

Ship HTML-file apps without the glue code.

Hello fellow hackers,

As web developers we rebuild the same basic pieces over and over. Not the fun parts, the boring parts you need before anything feels real: editing, uploading, sharing, collaborating, and the little UI moments where you have to stop a user and ask them a question.

Here's the kind of before/after HyperclayJS is built for:

Before (React) After (HyperclayJS)
import { useState } from 'react';
function Counter() {
  const [count, setCount] = useState(0);
  return (
    <>
      <button onClick={() => setCount(c => c - 1)}>-</button>
      <div>{count}</div>
      <button onClick={() => setCount(c => c + 1)}>+</button>
    </>
  );
}
export default Counter;
<button onclick="this.text.counter--">-</button>
<div counter>0</div>
<button onclick="this.text.counter++">+</button>

this.text.counter is a HyperclayJS helper: it finds the nearest element marked with the counter attribute and reads/writes its text.

This is the style HyperclayJS optimizes for: tiny, local handlers that set and read DOM-state.

The web platform has made progress. <dialog> is a good start for replacing modals, for example. But you still end up wiring a bunch of missing pieces yourself: styling, focus/keyboard behavior, stacking, scroll-lock, and an API that feels consistent across an app.

HyperclayJS is my attempt to fill in those gaps with a small, readable set of low-level tools. You can pick and choose what you want from it.

The point is fewer moving pieces and more locality of concerns. So you can stay in flow without hopping between 12 different components.


A few superpowers

  • Ship the artifact: create an HTML file, edit it, it auto-saves
  • Hyperclay Local: live sync your dev files to the web
  • Admin UI helpers: make a page editor without interfering with the viewable version

If you want the deeper "why" behind this direction, I spent weeks outlining my reasoning here: Read: The Plumbing Behind Everyday Magic

If you try it, hit reply with what you built (or what got in the way).

Happy hacking,

David

@panphora

The Plumbing of Everyday Magic

Introducing Malleable HTML Files

On my phone, I tap a button and a car arrives. I tap another and I have an apartment for the night. We've turned buttons on our screens into levers that move the real world.

These buttons are as intuitive and easy to use as turning on a faucet in your home. Just like the faucet, there's a lot of plumbing behind the scenes to make them work.

But what if, every time you turned on your faucet, you had to crawl under the sink, stare at a mess of pipes, and reconnect things until the water came back?

That's what it feels like to build software on the web in the year 2026.

Web development is riddled with trap doors between the act of creating and sharing a functional application. These trap doors break creative flow. What we need are surface-level artifacts—web documents you can use, edit, and share without having to go beyond your current HTML document.

I've spent a decade on this problem, and I think I've found one small, boring piece of plumbing that makes that kind of file possible.

The primitive is simple: an HTML file that can serialize its own state and POST itself to a save endpoint, making the file its own database. This isn't about replacing full-stack development—it's about creating shareable creative tools that shouldn't need it.


Creating vs. Debugging

When you're in creative mode, slipping into debugging is always accidental. And it always disturbs your flow.

I'm more artist than engineer—obsessed with how people experience interfaces. My craft lives at the intersection of people and screens.

When you're focused on making something for other people to experience, it's very important that you stay in flow. You're building a flow for other people, so it's helpful to experience it yourself as you build it—to understand what you're giving them. It's like writing a story: if you get interrupted mid-thought, you lose the thread, and it's impossible to get it back.

The interface is the faucet, up above. The part people touch and manipulate. But the moment I try to share it with other people, the magic evaporates.

Here's what those trap doors tend to look like in practice:

  • State sync: the UI "works" locally, but the moment you add a server, you're managing two sources of truth that can drift apart, conflict, or silently overwrite each other.
  • Schema lock-in: you're forced to commit to a data model while the interface is still changing week to week.
  • Orchestration and scope creep: production behaves differently than local, dependencies drift, and "one small change" becomes a refactor.
  • Auth scope explosion: "just associate data with a user" turns into roles, teams, identity providers, libraries, and security tradeoffs—I've watched a "save my work" feature turn into email verification, password reset, session handling, and permission bugs.
  • Deployment and ops: now you need migrations, updates, backups, monitoring, and a constant sense you're one mistake away from catastrophe—the day your certificate renewal fails or a background job silently dies, you realize "shipping" includes babysitting. You end up creating bash scripts to schedule deployments, backups, alerts, downtime detection—because what you built is now a live system with moving parts, many of which you didn't write yourself.

The moment the trap door opens is usually the moment you hook your front-end to anything external—an API, a database, a login system, a deployment target. You stop working on a flat surface and start managing a knot of interconnected services and configurations. It feels puzzle-like, and puzzles are seductive. But the puzzle is not the experience you came to build.

This is where my projects have died—not at the idea, not at the prototype, but at the handoff from "works for me" to "works for other people." The work stops being shaping an experience and becomes operating complex, interconnected systems.


Deploying operational software on the open web

Years ago, I built a side project called Journeyship: an animation scene builder where you control every pixel and every character. I worked on it in stolen moments—on the train, in cafés after work, on the couch. I stitched it together piece by piece.

It was complicated in a satisfying way: canvas drawing, caching, timelines, little animated pixel-art characters you'd build up pixel by pixel. I got it good enough that other people wanted to use it.

Then I did what you do when you want to share something: I deployed it.

That meant reading a book-length worth of documentation and running arcane commands on a $5 Ubuntu box on Digital Ocean.

I installed Redis as my database, left a port open, and within a month my server got hacked.

I still remember the moment I realized. I was checking my email when I saw the alerts arrive: "Monitor is down: Journeyship." Then, from Digital Ocean: "Networking disabled." I clicked through and saw my server had been taken down. Everything was gone. Not just my work, everyone's work. Every animation people had made, every pixel they'd placed, erased because I'd misconfigured a firewall.

I felt sick. I emailed the users I could reach. Most never responded. The app went offline, and I couldn't bring myself to put it back up. I'd lost something harder to recover than data: my confidence that I was capable of keeping something online.

Real plumbers set up pipes once and forget them. I'd signed up for daily maintenance on infrastructure I never wanted to own.

Yes, there's a specific lesson here: put a firewall in front of your app and store backups off-site. But the bigger lesson is how easy it is for a creative person to wander into the danger zone between making an experience and operating a fragile machine on the public internet.

You came to make a faucet. You accidentally signed up to re-plumb a building.

That's why I've spent the years after Journeyship learning the unglamorous parts of keeping software online: provisioning, deployments, security, backups—not because that's where I want to be, but because I wanted "make a faucet" to stop meaning "re-plumb a building."

That mismatch, between the surface you came to shape and the machinery you inherit when you share it, is the real problem I'm pointing at. And eventually, it led me to a different way of thinking about web artifacts entirely.


The divide between the interface and the plumbing

The weird part is that even plumbers don't live under the sink the way web developers live in the backend of their apps. In web development, the surface is where most of the users' interactions happen, but the moment you try to share it, the floor gives way. There's a top world and a bottom world: the interface and the plumbing.

As a UX-focused maker, the interface is what I came to make. The thing people see working. The thing people use.

The plumbing is what you end up maintaining so strangers can safely touch what you made.

+-------THE_EXPERIENCE--------+
| UI / Interaction Design     |
| HTML / CSS / JavaScript     |
| Canvas / WebGL / Components |
| The actual idea             |
+---------DEBUG_MODE----------+
| Hosting, domains, SSL       |
| Secrets, auth, permissions  |
| Databases, backups          |
| Security, updates, ops      |
| Build pipelines, config     |
+-----------------------------+

If you're a professional engineer, you can learn the lower half, and plenty of people do.

But if you're a creative trying to ship interactive work, someone whose whole process depends on staying in flow, this is where projects die. You're like an author who finally finished writing a great novel, only to discover you also need to construct a printing press.

The plumbing exists for real reasons. It's where other people's data begins. It's where security and uptime matter for real. And when it's done well, it's genuinely magical.


"We've already solved this. We have frameworks."

We have frameworks, platforms, starter kits, "one-click deploy," and a thousand clever ways to flatten the stack. These tools exist for good reasons. They handle authentication, migrations, caching, scaling—genuine complexity that matters for production software serving thousands of users.

And yet most of these tools still pull you into the plumbing. You're still debugging configs. You're still patching leaky abstractions. "One-click deploy" often means "one click after you've accepted an ecosystem's 30 pages of documentation and a pile of details you only learn by shipping mistakes."

The frameworks handle real complexity, but they don't eliminate the trap doors; they give you tools to manage them. It's still your job to know where they are.


Building the printing press before writing the book

There's a related issue here that corrupts the entire creative process: because of how complicated we know deployment can be, a lot of the time us developers start by building the printing press instead of writing the book.

If you're building a full-stack resume generator and you haven't created at least 20 resumes in Google Docs first, you probably shouldn't be dedicating that much time to solving that problem.

A plain HTML file is a low-level primitive, even more flexible than a Doc. Want to build a resume builder? Go for it. But build 20 resumes in something closer to the UI layer first and see if people actually want it.

What if the web had a better "surface-first" artifact? Something you could shape directly, share immediately, and then you'd only optionally descend into its plumbing later?

I'm not talking about web development as a whole. I'm talking about a specific kind of making—creating malleable, shareable experiences. The kind of thing Canva, Replit, or Bubble let you build. Your own personal file format, shaped by you, usable by others.


Getting tired of splitting the world in two

I once built an Express.js app for creatives to sell their services: public profiles they owned, service listings, a visual timeline, and a contact form where clients could submit a brief.

Month one was great. The design felt done. The experience felt real on my machine.

Then I tried to ship it, and the trap doors opened: wiring UI state to the backend, deciding how to model everything in a database even though the interface was still evolving, getting dragged into auth decisions, and watching the whole thing balloon into a second job.

Eventually I got tired of thinking about it and did something almost embarrassingly simple: I bundled the entire UI state into one big JSON blob and persisted it directly to a file on the backend.

No "frontend state" versus "backend state." No reconciliation. No fragile mapping layer. The UI was the truth, and saving meant saving the truth.

It wasn't "the correct architecture" according to the usual standards. But it was the first time the project felt flat again—like I was back on the surface.

That insight led me to build Remake.js, a framework that used special HTML attributes to auto-convert between DOM and JSON. Attach key:title and object to elements, and the library would handle persisting deeply nested data structures automatically. CRUD apps became trivially easy. I had paying customers. Someone told me it got banned from a hackathon for being "too efficient."

But people kept asking for two things: to build their own backend on top of it, or to customize the magic behind how it worked. I kept adding magic to make things "just work." Auto-merging data, custom renderers, more and more abstraction. The framework got heavier. The trap doors didn't close; they just moved.

That's when I realized I needed something simpler. Not a framework, but a primitive. Something so close to the native web that there was nothing to fight against.


Self-contained, malleable artifacts are the creative world's best primitives

I want something close to a Photoshop for web software: a tool that makes creation feel direct and tactile, and makes distribution feel like a natural continuation of creation.

In a good creative tool, once the work looks right in your hands, you're basically done. You shouldn't have to spend another 70% of the effort converting your idea into something other people can use. There's no reason for it—if it's usable by you, it should be usable by other people too.

Good tools don't hide complexity behind a curtain—they eliminate the need for it. The surface is honest.

If it looks like a button, you can press it. If it looks like an app, you can use it and share it.

We've seen glimpses of this before. Spreadsheets are the simplest proof. A Google Sheet is malleable, shareable software that can process a lot of data. Other people can change it while you're viewing it, and their changes persist. Earlier tools like HyperCard and Flash had a similar feeling: the creative environment and the deployment environment were essentially the same. The artifact was the experience.

What makes HTML different is freedom. HyperCard gave you cards. Flash gave you timelines. TiddlyWiki gave you wikis. HTML gives you a more flexible foundation to build any user experience imaginable.

So why does publishing an interactive experience still so often feel like building an entire CMS from scratch?

Tools that try to reinvent the stack tend to struggle. VapidCMS, Glitch, Mavo, Meteor.js, Dark Lang. Each got a lot right, but it's hard to get people to change their way of working. The lesson: build close to what people already know. Malleable HTML files add a few primitives to standard HTML. You understand 99% of it already.


Software's best creative file type is hiding in plain sight

One way to see how backwards web development has gotten is to look at the simplest web artifact: the HTML file.

Most creative files—Word docs, Photoshop images—let you view and edit in basically the same place. But HTML has two faces: a consumer face that's read only and can't persist changes on its own, and a developer face that drops you straight into the plumbing. There's no obvious "middle" where UX-focused makers can build a suite of creative tools on top of it that ordinary people can use.

And that's tragic, because HTML is already the web's native document format. It's already a container where UI and data can live together. It's already portable—you can email it, put it on a thumb drive, host it anywhere.

We don't need a proprietary runtime or a platform vendor's permission. The web is the platform. It's the best platform ever developed, with a universal runtime, a world-wide audience, and the ability to build anything on top of it.

The insight here isn't that self-contained files are powerful. TiddlyWiki proved that over 20 years ago, with a devoted community that still uses it daily. The insight is that persistence plus UI ownership is the missing combination. TiddlyWiki gives you its interface. Malleable HTML files let you build your own. You design the admin UI and the viewer UI in the same file, and the admin layer strips itself before saving. In the age of AI-assisted coding, people don't want someone else's admin interface. They want to shape their own.

As Ink & Switch puts it in Malleable software:

"Modification becomes routine, not exceptional. Adaptation happens at the point of use, not through engineering teams at layers you can't edit or control."

That's the north star here: keep adaptation on the surface, inside the artifact, without falling through the floorboards.

The question isn't "why HTML?" It's "is now the time to start treating HTML files as self-contained creative artifacts?"

If we treated HTML like a creative artifact—something you can use, shape, and share in one motion—then "deployment" wouldn't be a trap door. The web wouldn't require you to become a systems administrator just to let someone else shape a malleable artifact you made.

So the question becomes: what's the smallest, most boring piece of plumbing we could add to an HTML file so it can keep the changes people make to it?


Surface-level guarantees

Ink & Switch nails the motivation in Local-first software:

"The cloud gives us collaboration, but old-fashioned apps give us ownership."

That's why these guarantees start with persistence and portability—because ownership is what keeps the artifact real over time.

If we want artifacts that don't turn into trap doors, they need a few non-negotiable properties:

  1. Persistence: changes save reliably without inventing a backend.
  2. Portability: the artifact is self-contained enough to move, copy, and share without fragile setup.
  3. Editor and viewer unified: the making surface and the using surface are the same place—not totally separate environments for developing the software and using it.

That's the core. Everything else—live sync, file uploads, collaboration—matters a lot, but it builds on top of this core.

The requirement is simple: make the artifact itself the unit of creation and sharing, so "publish" doesn't mean "become a systems administrator."


Malleable HTML files: making HTML files into creative artifacts

The answer is to give an HTML file one boring, reliable piece of plumbing: a way to save.

Malleable HTML files are a way of making new kinds of creative document formats that are just a plain HTML file underneath. They let you design self-contained, malleable artifacts while keeping complete compatibility with HTML and the native web.

The core idea is the simplicity of the data model: everything in one file. You don't have to think about where the data is going or coming from, or how to manage state across a pile of services. Unlike Google Docs, Sheets, or TiddlyWiki—where you're limited to their UI and data formats—you control both the input and the export format, and how everything is displayed. You have 100% control over the format, the design, and the interface. You present the result of user edits however you want to.

Malleable in two ways. For the developer, adding features is fast because it's just front-end code: HTML, CSS, a bit of JS. You add UI logic; persistence is handled in the background. For the user, if the author builds an admin interface into the artifact, anyone who forks it inherits the same editing controls. A contenteditable field, a drag-and-drop list, whatever you built, they get. The result is a flat artifact that works from every angle: a creative file that's also its own editor.

In practice, it's like a mini database with a really nice UI, packaged as a single file you can put anywhere. Anything that can live in a web document can live in a malleable HTML file: text, charts, interactive elements, media—whatever state you can keep in the document itself or in an attached file.

The payoff is that you get the power of tools like Sheets and Slides, but with a purpose-built interface for your users' use case.

Build the faucet and you're done enough to share. The pipes hide away in the background.

How it actually works

The mechanism is very simple: an HTML file that can serialize itself and POST to a save endpoint.

When you edit the page, JavaScript updates the DOM. When you save, the page serializes its own HTML and sends it to an endpoint that overwrites the file. The file is the database. Changes are optimistic on the client and eventually consistent on the server—which in practice means they persist as soon as you have a connection to a server, whether on localhost or using a platform.

That's it. No database migrations, no state sync, no schema. The artifact contains its own truth, and saving means overwriting itself.

This idea has a real research lineage too. In Webstrates: Shareable Dynamic Media, Klokmose et al. describe the same blur I'm aiming for:

"They turn web pages into substrates, i.e. software entities that act as applications or documents depending upon use."

That's the point: a page that behaves like a tool and a document at the same time, with its state living in the thing you share.

The trickiest part isn't the save mechanism. It's thinking of one document as two documents. The admin UI and the viewer UI live in the same file. You design both, but only the author (or someone with edit access) sees the editing controls.

In practice, this is simpler than it sounds. You overlay edit controls on the page: inline editing, popover buttons, drag handles. Then you hide them for viewers. The page editor looks like the thing it outputs. What you see is what they get.

For local development, the endpoint can be a tiny localhost server pointing at a folder. For sharing, it can be a hosted service. The HTML file doesn't care—it just needs somewhere to PUT itself.

I've been building this for three years. It started as a 20-line Node script. It's now a platform called Hyperclay, with a free local app and an open-source JS library. But the core idea hasn't changed: give an HTML file a way to save, and the trap doors close.

A day with a malleable HTML file

Imagine a high school teacher building a little "lab rubric" tool for her class. It's just a page: a few sliders, a comment box, a rubric table that totals points and generates feedback text.

On Monday night she tweaks the wording and rearranges the rubric categories until it feels right. She hits Save. Nothing "deploys." There's no database to migrate. The file itself now contains the updated rubric and the latest default state.

Tuesday morning she emails a link to that file to another teacher. He opens it, uses it in class, and changes a few categories to match his lab. He hits Save. He sends his version back. Now there are two forks of the tool—like two versions of a spreadsheet—each perfectly usable, each self-contained.

Later, when she wants a "shared school-wide version," that's when she chooses to add more plumbing: user accounts with admin roles and a relational database. But crucially, she didn't need any of that to get from "finished enough" to "usable by other people." The first publish step was just sharing a link.

On the Hyperclay homepage, you can try four malleable HTML files right now: a developer log, a minimal writing tool, a kanban board, and a landing page builder. 800 people are on the early access list.


The boundaries of malleable HTML files

Let me draw the boundary clearly, because this matters.

Malleable HTML files are not trying to replace full-stack frameworks. They're not ideal for apps that depend on heavy backend computation, third-party API orchestration, or complex relational data (social graphs, role-based permissions). Those are real domains, and they deserve real infrastructure. The plumbing exists for those cases because it solves genuine problems.

The claim here is narrower: there's a large category of interactive experiences that should be publishable like documents, not like services.

A portfolio builder. A visual essay maker. A journaling app. A budgeting tool. An image editor. A presentation builder.

These things shouldn't require you to stand up a server, configure a database, implement authentication, and monitor uptime. They should be files you can make, save, and share.

The trade-off is intentional. Malleable HTML files optimize for the moment of creative completion—the moment when what you've made is ready to exist in the world—at the cost of capabilities you'd need for a different kind of project. If you're building the next WordPress or Figma, start with a malleable HTML file, but move beyond it as you scale out your systems. If you're building a thing you want to finish and ship this weekend, maybe it's all you need.

Most tools never need to graduate. The browser's native APIs (canvas, audio, drag-and-drop, geolocation) are powerful enough that external API calls aren't necessary for many types of software. You graduate when your data outgrows a single file, when you need a relational database, or when paying customers expect enterprise features. For everything else, the browser is enough.

Common objections

What about Vercel, Netlify, Firebase? You're locked into a proprietary platform. You don't understand most of the stack. It's not portable, not forkable. You have to track documentation, API changes, and hundreds of dependencies. It's serious infrastructure for a single portable experience.

What if two people edit at the same time? Both saves get backed up. Worst case, you restore a previous version. For real-time collaboration, live sync keeps everyone's edits synchronized.

"This won't scale." It scales the same way Google Docs scales: plenty fine for what it's for. Most personal software doesn't need millions of rows. If you hit 100,000 table rows, you've proven usefulness. Now it's time to build a full-stack app.

What about security? The model is simple: trust the author, like WordPress or Webflow. Your artifact contains nothing private. It's just HTML. Anyone with edit access can reveal the admin UI by enabling the right scripts. Share links work like Google Docs: you choose who can edit.

For single-user tools and trusted collaborators, this is exactly right. When you need real security boundaries, like role-based permissions, audit trails, or untrusted users, that's when you graduate to real infrastructure. The trap doors move to later in the development process.


What the web loses when everything is a service

When publishing requires an ops stack, the web gets fewer small, weird, personal tools.

I miss the MySpace and Geocities era—when everyone had their own malleable corner of the web. It was chaotic and alive. People owned their spaces and shaped them however they wanted.

That energy mostly died. But it doesn't have to stay dead. What if we could have that again—but this time with shareable artifacts that others can use, remix, and build on? Not just pages, but tools. Not just for yourself, but shaped alongside other people.

Surface-first artifacts are a way to lower the cost of weirdness.


Let creativity flow

Every trap door is a chance for a project to die—not from a lack of vision, but from a mismatch between what you came to make and what you're forced to make instead.

Ever since building Journeyship, I've been asking a simpler question: what's the smallest change that would have let me share it without becoming a server administrator?

The answer I keep coming back to: an HTML file that can save itself.

Not a framework. Not a platform. Just the missing primitive—persistence—added to the artifact we already have. A file you can make, shape, and hand to someone else, the way you'd hand them a spreadsheet or a Google Doc.

That's what malleable HTML files are. That's what I'm building.

If you've ever watched a project die in the gap between "works for me" and "works for others," you know why this matters. The web doesn't need more frameworks. It needs fewer trap doors.

Planning Canvas.

A tiny app you can fork, hack, and ship.

Hello fellow hackers,

This is what it looks like when an HTML file comes with its editor UI built in.

I promised you Hyperclay lets you treat an app like a document: one artifact you can edit while it runs, share as a URL, and export as a file.

Planning Canvas

An infinite sticky-note surface for thinking. A URL you can share + a single HTML file you can export and keep.


Features

  • Click a card to edit (it's just contenteditable text)
  • Drag cards by the handle on the left (pointer events, works on touch too)
  • Resize from the bottom-right corner
  • Set priority/status (Critical / High / Medium / Low / None)
  • Search across card text & status
  • Clone or delete via the three-dot menu

It's all just DOM state

What I love about this example is what's not in the JavaScript.

There's no state object to sync. No database to persist to. When you drag a card, its position updates in the DOM: style="transform: translate(300px, 20px)". When you edit text, it stays edited—it's just contenteditable. When you change status, it's a native <select> with selected.

The JavaScript handles behavior—dragging, resizing, the menu. But the data model is the DOM itself. When you save, the page serializes its own HTML and POSTs it. No ORM. No schema. No state reconciliation.

This is the point of Hyperclay: when state lives in the document, distribution becomes a continuation of creation. You don't "finish the app" and then go do ops. You just share it.


Try it yourself

If you want a quick exercise after watching the video: open the source, change the default status options, or add a "Done" state, or tweak the card defaults. Then re-share the URL.

If you try it, reply with:

  1. What tweak did you make (and did you export the HTML file)?
  2. What did you expect to be editable, but wasn't?
  3. What felt annoying or fragile in the flow?

Happy hacking,

David

@panphora

Thinking in Hyperclay.

An HTML document that acts and feels like an application.

The short version

An HTML file can be anything: a video editor, a spreadsheet, a game. But it's the only creative file format without a native editor of its own. Hyperclay lets you add one for your specific use case.

  • Pick a root element for your behavior and store state in attributes.
  • Gate UI with option: blocks.
  • Keep behavior local with small onclick/oninput handlers.
  • Let the DOM be the database; reach for JSON only when you need structure.
  • Ship the file. The artifact is the app.

The Mindset Shift

Traditional web apps are built on separation of concerns. Frontend here, backend there. State in one place, UI in another. Multiple files, build processes, API endpoints. Keep things DRY. Don't repeat yourself.

Hyperclay inverts this. You optimize for locality of concern: if you look at a small chunk of HTML later, you should understand how it works (and how to change it) within a few seconds. It works because the state you need is right next to the pixels—on the elements themselves—not in some distant store you have to mentally reconstruct.

  • State lives on elements. Prefer attributes over hidden JS state.
  • Behavior lives next to the click. Start with inline handlers; extract only when it stops fitting.
  • The DOM is the data model. Don’t mirror it into a second source of truth unless you have to.
  • Hide, don't inject. Keep admin UI in the document and reveal it via state. Except for scripts, disable those with the edit-mode-resource attribute.
Traditional Web App Hyperclay App
Separate frontend/backend Single HTML file
Database queries DOM as database
API endpoints Direct DOM manipulation
Build process No build needed
Complex state management DOM attributes as state

A Simple Recipe

  1. Choose a root element and a tiny vocabulary of state attributes (like mode, selected, filter).
  2. Write UI variants as normal DOM branches.
  3. Gate those branches with option: blocks.
  4. In handlers, find the root with nearest and flip an attribute.
  5. Let the DOM persist the result.
<div status="not-complete">
  <button onclick="this.val.status = this.val.status === 'complete' ? 'not-complete' : 'complete'">
    Toggle Status
  </button>

  <div option:status="not-complete">This task is not complete.</div>
  <div option:status="complete">Done!</div>
</div>

The DOM as Database and State Machine

In a Hyperclay app, state is stored directly in the DOM: content, transforms, layout, text. If the user edits text, it stays edited. If they move something, it stays moved. The document is the database.

The fun part is that the DOM is already a tree: nested nodes and branches. Each subtree is a natural component. Tag a root and you get encapsulation for free.

Attributes do triple duty. They store behavior, information, and appearance—at once. A single attribute toggle can cascade through a whole subtree and flip the UI like a state machine.

<div settingspanel="closed">
  <button onclick="this.val.settingspanel = this.val.settingspanel === 'open' ? 'closed' : 'open'">
    Toggle Settings
  </button>
  <div option:settingspanel="open">Settings content here...</div>
</div>

Change state somewhere once, and the UI changes everywhere it needs to. No wiring. No syncing. It’s no big deal.

When you need structured data

Sometimes you really do want arrays, maps, or nested records. In that case, keep your “database” inside the document with a JSON script tag.

<script type="application/json" id="appData">{"items":[{"text":"Buy milk","done":false}]}</script>

const [items, setItems] = useState(
  JSON.parse(document.getElementById('appData').textContent).items
);

Inline handlers should stay short. If yours start to feel cramped, call a named function or use a tiny helper library. Hyperclay ships one option (all.js), and jQuery also fits this style well.

<!-- all.js keeps inline code small and readable -->
<button onclick="all.item.filter(el => el.dataset.status === 'draft').remove()">
  Clear Drafts
</button>

Flat and Readable

Your document should feel like a state machine. Something flat. Declarative. Not a web app with GOTO-like AJAX calls that trigger backend functionality, that send responses, that end up in some other piece of higher-level state somewhere else in your app.

No. It's just a DOM tree.

You change an attribute. The UI responds. That's it.

For behavior, use inline event handlers: onclick, oninput, onsubmit. They're bite-sized pieces of functionality, local to where the action happens. Everything fits in your head.


Don't use Hyperclay if:

  • You need deep backend integrations as the core of the product.
  • You need many pages that share structured data and templates (shared nav/footers/models).
  • Your UI is so complex you need a component system just to keep it thinkable.
  • You need total control over auth flows, redirects, and system behavior end-to-end.

Hyperclay is artifact-first: start here for speed and malleability; migrate to a stack when it earns it.


Edit Mode + View Mode

It's like dark mode and light mode—just a toggle between two views.

Both views are nearly identical. One has the editable UI built in: controls, inputs, outlines. The other is clean, ready for visitors.

Flip the switch.

Mini demo
mode: viewedit

My little tool

A tiny document-app that can be edited and shared.

This hint is in the DOM too—just hidden in view mode.
View mode: the artifact is clean. No controls.
Edit controls (hidden, not injected)

That’s the trick: a single state attribute flips what’s visible. The controls stay in the document; the surface stays honest.


Hide Don't Remove

The trick: hide admin controls instead of removing them.

Use option: attributes for conditional visibility. The whole app is always loaded—you just reveal different parts based on state. When the page saves, elements marked for edit-mode-only get stripped out automatically.

<div user-role="guest">
  <div option:user-role="admin">
    Admin controls here...
  </div>
</div>

This keeps things simple. No dynamic injection. No complex loading logic. The document is complete. You just show what's relevant.


Try It

Open any Hyperclay app and inspect the source. The “app” is just a document with stateful attributes, plus a small amount of local behavior.

  1. Find a state attribute near the top-level container (often a single “mode” or “role”).
  2. Change it and watch UI branches appear/disappear.
  3. Edit some content directly in the page.
  4. Export the HTML file and host it anywhere.

The Result

A Hyperclay app is a document you can pass around. Host it anywhere. Edit it while it runs. Share it as a URL or a file.

It's not simpler because it does less. It's simpler because everything is in one place, working together, visible at a glance.

That's thinking in Hyperclay.

Your Hyperclay Beta Invite.

72 hours to claim your spot.

Hello fellow hackers,

Here's your beta invite to Hyperclay.

$15/mo or $120/yr — instant access

This link expires in 72 hours (midnight ET)

Sign Up Here

Success in 30 minutes

  1. Clone Planning Canvas and make one meaningful tweak (fields, defaults, styling, or workflow).
  2. Publish the URL and share it with one person.
  3. Export the HTML file so you "own" the artifact as a portable file.

Optional: if you installed Hyperclay Local, enable local↔cloud sync.

Hyperclay lets you build a real web app as a single HTML file—editable while it runs. State lives in the document, so sharing is simple: a URL or an exported file.

This is for web developers who want to ship small interactive artifacts fast, without adopting a whole stack for every experiment.

If you've followed my earlier Remake.js writing (remaketheweb.com), Hyperclay is the work that grew out of it: less stack, more artifact.


Three things to try first

  1. Clone an existing app.
  2. Paste in an HTML file (or one generated with AI) and start making it editable.
  3. Explore HyperclayJS and see how treating the DOM as a state machine changes how you build.

Expect bugs—reply if anything breaks or feels confusing.

If you want a deeper tour: Watch the Video

Sign Up Here (expires in 72 hours)

P.S. Don't get trapped in the plumbing. Discover the everyday magic of building on the web again.

Happy hacking,

David

@panphora