
On the web
A whole animation in 140 characters of JavaScript
Dwitter is a gallery of animations whose entire source is 140 characters or fewer. One function runs every frame on a canvas, and people remix each other's math for fun.
A grid of orange and cream tiles ripples and folds on itself, endless
and hypnotic. Below it sits the entire program that draws it, and a
counter in the corner reads 140/140. Every character it is allowed,
spent.
dwitter.net is a community built around one hard rule: your animation's source code has to fit in 140 characters or fewer. Each entry, a "dweet," is a single JavaScript function called sixty times a second with the elapsed time as its argument, drawing onto a canvas. That is the whole canvas the coders get, in both senses, and the top-rated ones are astonishing for the size. The tile pattern above earned hundreds of votes and nine separate remixes.
The number is not arbitrary. 140 characters was Twitter's message limit when the site launched in 2016, the year before the limit doubled, and the name "dweet" is the pun saying so out loud. The founding bet was that a whole animation could travel inside a single tweet, source and all. Twitter moved on. The constraint stayed, because it turned out to be a good one.
The demoscene lineage is not figurative. Dwitter launched at the Norwegian demoparty Solskogen in 2016, where it won the wild compo, and its makers, Sigve Farstad and Andreas Selvik, met at university in Trondheim and caught the bug from demos that packed fifteen minutes of visuals into 64 kilobytes. Selvik built the site itself as a side project to learn Django, and the whole platform is open source, Python underneath, with more than twenty contributors to date.
How far the ceiling actually goes
The scene's outer limit is best measured in city blocks. Frank Force, one of the most ruthless golfers on the platform, built City in a Bottle: a raycast, procedurally generated city with windowed buildings, cast shadows and distance fog, in 256 bytes of HTML and JavaScript. Not kilobytes. The whole program is smaller than two dweets laid end to end.
His writeup walks through every trick, and they are gloriously unreasonable. There is no trigonometry anywhere. Building heights come from a bitwise XOR of the grid coordinates, the window textures from AND and modulo arithmetic, and the render loop is a 9 millisecond timer doing an impression of 60 frames per second. The piece ran at the Revision demoparty in 2022 and was later reborn as a 256-byte shader running in full HD at the same impossible budget.
That is the kind of neighbor a dweet grows up next to. The compo context matters too: demoparties run size-restricted categories the way track meets run weight classes, and an entry is projected on a big screen in front of a hall that knows exactly how expensive every effect on it should have been. The applause is calibrated. Dwitter bottled that and left it running year round.
The whole toolkit is five letters
The way anyone fits a scene into 140 characters is a mix of math and
merciless shorthand. Every dweet gets the same rig: c, a canvas
1920 pixels wide by 1080 tall, x, its 2D drawing context, S, C
and T as one-letter names for sine, cosine and tangent, and
R(r,g,b,a) to build a color string. One function, u(t), runs
every frame with t counting seconds since the start. That is the
entire environment, and nothing else is provided on purpose.
Do the arithmetic on what the budget buys. A 1920 by 1080 canvas is 2,073,600 pixels, repainted 60 times a second, which means each of your 140 characters is answerable for roughly 14,800 pixels per frame. No image on the web works harder per byte.
The R helper is the one concession to comfort: R(255,128,0)
hands back the string rgba(255,128,0,1), twelve characters
typed where the quoted literal would cost nineteen, and in this
economy seven characters is a generous gift.
There are no assets and no libraries, no room for them. Every frame is computed from arithmetic, so a whole moving texture comes from nesting sine and cosine of the pixel coordinates and the clock, and every character fights for its place: semicolons get dropped, variables get reused, and the coercion tricks that would fail a code review win compos here.
Read enough top entries and the local idioms start repeating.
Assigning to c.width wipes the whole frame, because a canvas
clears itself whenever it is resized, so the classic opener
spends ten characters on c.width|=0 where an honest
clearRect call would cost twenty-six. Skipping the wipe
entirely is a move too: frames pile up on each other and the
smear becomes the aesthetic.
De-golfing is how I finally learned to read them. Take a top dweet, paste it into an editor, give the one-letter variables real names, split the comma chains onto their own lines, and a terrifying 140-character string turns into fifteen lines of ordinary loop you could have written. The compression is the sport; the underlying math is usually three ideas.
If you have ever written a fragment shader the shape will feel familiar: one small function, fed the clock, conjuring the picture from arithmetic. It is the same move a GPU makes, performed by hand on a 2D canvas.
Remix is the engine
The social part is the good part. You can remix any dweet, so a clever formula gets forked and twisted by a dozen people, each shaving a character here to afford a color there. It is code golf as a spectator sport, and the scoreboard is genuinely beautiful.
The lineage stays visible, too. Every remix links back to its parent on the entry's page, so you can walk a formula's family tree generation by generation and watch a plain spinning shape acquire lighting, then color, then a sense of humor, one 140-character descendant at a time.
The family tree, by byte count
Dwitter is one branch of a size-coding family where every branch carries its own number:
- js1k ran themed rounds from 2010 to 2019 at 1,024 bytes per entry, demos and games and ray tracers, and the full archive of a decade of winners still loads today.
- Bytebeat plays the same game on your ears: one line of C, bitwise operations on a counter, 8-bit samples at 8 kilohertz, and out comes music. Viznut's 2011 writeup traces the whole movement back to a 23-byte Commodore 64 demo.
- The party compos go smaller still: 256-byte categories at events like Revision, where City in a Bottle took its bow in 2022, sit at the bottom of the scale and still produce entire worlds.
Same instinct everywhere: pick a budget that sounds impossible, then make the impossible budget the medium.
Posting needs nothing but a login and 140 characters of nerve. The about page holds the full rig plus an FAQ, and the top chart holds a decade of formulas to learn from, which is the intended way in.
My suggested route, after a week of lurking: sort by top of all time, pick the entry that most offends your sense of what 140 characters can hold, de-golf it, then change one constant and watch what happens. Congratulations, you are remixing. The button on the site just makes it official.
The same maximum-from-minimum idea, even smaller: an animation from a single line of code.

Next up
Spin the planet, hear it sing