Write Solana programs in HTML.
HTMLSOL compiles plain HTML tags into Solana programs. Tables become accounts, forms become instructions, and the tag you forgot to close is a compile error with a line number, not a surprise on mainnet.
You write the tags.
HTMLSOL writes the checks.
Left, the increment form from counter.html. Right, the C the compiler writes for it. It's not a mock-up: this page runs the compiler while you read.
You wrote 7 lines. The compiler wrote the rest, and it never forgets a closing tag.
The same counter, four languages
One counter program written in HTMLSOL, TypeScript, Rust and hand-written assembly, measured on the things developers actually complain about. HTMLSOL wins five of six. The sixth is a cultural problem, and we are working on it.
Every tag, and what it costs
The whole language fits in one table. Compute units are the compiler's own estimates per use; your real numbers come from the logs after deploy. Full reference in the docs.
| Tag | Compiles to | Est. CU |
|---|---|---|
| <program id> | The program and its entrypoint, with an instruction switch. | — |
| <table id> <td name type> | An account layout. Eight-byte discriminator, same as Anchor's, so explorers read it. | — |
| <form action> | One instruction. Its discriminator is sha256("global:name"). | 60 |
| <input type="signer"> | A signature check on that account. | 5 |
| <input type="account" of mut> | Owner, size, discriminator and writable checks, then a typed pointer to the data. | 29 |
| <input type="u64"> | A length-checked little-endian read from instruction data. | 6 |
| <require if error> | A custom error from 6000 up, with the file and line it came from. | 4 |
| <set> <add> <sub> | Assignments and checked math. Overflow fails the instruction. | 5 |
| <a href="system:transfer"> | A cross-program call to the System Program that moves lamports. A hyperlink that pays. | ~1,250 |
| <marquee times> | A loop, 1 to 64 turns. It has to stop, unlike the ones on your old homepage. | 3 / turn |
| <blink> | A line in the transaction logs. | 100 + length |
| <center> | Nothing. Your code is centered anyway. | 0 |
The fine print
Byte and compute numbers on this page come from the compiler's cost table, not from a validator. Measure the real thing with solana logs after you deploy.
A log line costs about 100 compute units plus its length. Blink with intent, the way you did in 1998.
A marquee that scrolls forever doesn't compile. The runtime would stop it at 1.4 million compute units anyway, so we stop it first.
Your browser forgives unclosed tags. HTMLSOL doesn't: an unclosed <form> is an error with a line number, and unknown tags get a warning.
The compiler writes C against solana_sdk.h. The .so comes from clang in Solana platform-tools, the same toolchain the official C examples use.
No Rust.
No semicolons.
Four steps from an empty file to a program on chain. The IDL is Anchor's format, so Anchor clients and explorers read it unchanged.
Write a .html
One file, any editor. Notepad counts. If it opens in a browser, you're halfway there.
programs/counter.htmlCompile
Paste it into the Playground, or call compile() from the module. You get C, the IDL and a client.
compile(src)Build
Solana platform-tools turn the generated C into a native SBF binary.
make · clang --target=sbfDeploy
Ship it like any other program. Again upgrades it in place.
solana program deployRight-click your program and read it. Like the web used to work.
Anchor format with discriminators, accounts, args and errors.
One web3.js instruction builder per form, generated from the IDL.
Every require gets a code from 6000 up and the line it came from.
Built in public
The big milestones. Everything smaller lands in the changelog.
<table> accountsRELEASED<form> instructionsRELEASED<a> transfersRELEASED<iframe> any-program callsPLANNED