Camping (Ruby framework)
Camping is why the lucky stiff's miniature Ruby web framework - a complete MVC stack that fits in a single source file of a few kilobytes, small enough to read in one sitting and strange enough to have changed how Ruby thought about web frameworks.
Created by why the lucky stiff (_why), with later maintenance by Magnus Holm, Karl Oscar Weber and the Camping community
Camping is a Ruby web framework that is famous for a single property: it is tiny. The framework’s entire implementation lives in one file, and the project enforces the constraint with a test in its Rakefile that fails the build if that file grows past a byte limit. For most of Camping’s life that limit was 4,096 bytes, which is where the original tagline - the 4k pocket full-of-gags web microframework - came from. It has since been raised twice, and the repository now describes itself as the 5k pocket full-of-gags web microframework.
Inside those few kilobytes is not a toy. Camping is a genuine Model-View-Controller framework with routing, controllers, views, sessions, helpers, a server command and a project layout. The premise, stated in its own README, is that you should be able to keep a complete fledgling web application in a single file like an old CGI script, but organise it the way Rails would - and then split the models, views and controllers into separate files later, if the thing you built turns out to matter.
It was written by why the lucky stiff, and it shows. Camping is one of the small number of software projects that is simultaneously a working tool, a joke, and an argument about what programming should feel like.
History and Origins
In January 2006, Ruby on Rails was roughly two years old and had made Ruby famous. _why - the pseudonymous author of Why’s (Poignant) Guide to Ruby, Hpricot, Markaby, and later Shoes - was not much of a Rails user. On January 18, 2006 he posted Camping is a Microframework to his blog RedHanded; the project’s CHANGELOG dates the 1.0 checkin to the day before.
The announcement post is characteristic. Rather than a feature list, it opened with the framework’s source printed out as a dense mural of Ruby, the whole thing visible at once. In the comments, asked whether Camping could handle e-commerce, _why suggested Rails - then reversed himself on hearing the operation in question was a small mail-order outfit: now you’re talking!! That exchange is Camping’s scope statement. It was for the small thing you would otherwise not have built at all.
Development was fast through 2006. Camping.goes - the method that generates a complete application namespace under a name of your choosing - arrived in 1.2 that same January. Sessions, WEBrick and Mongrel handlers came in 1.4 in April. Version 1.5, in October 2006, made the ActiveRecord dependency lazy, loading it only if an application actually referenced a model. A 1.6 was written and never released.
Then, in August 2009, _why deleted his accounts and websites and disappeared from public view. Camping was one of several widely-used libraries suddenly without an author. Unlike some of his other work, it survived: the code was MIT-licensed, mirrors of the source existed, and a group of Ruby programmers - Magnus Holm foremost among them - moved it to GitHub and kept going. The gemspec still lists why the lucky stiff as the author, and always has.
Design Philosophy
The size limit is the design. Most frameworks talk about minimalism; Camping made it a build failure. The Rakefile’s check:size task compares lib/camping.rb against a hard constant and errors out if it is over. A companion check:lines task rejects overly long lines, so the constraint cannot be met by simply deleting newlines. Every feature proposal has therefore had to answer a question no other framework asks its contributors: what are you willing to remove to fit this in? The 2.3 release notes record the outcome bluntly - “Increase camping test limit to 5120 bytes. We needed just a bit more space.”
Two copies of the truth. Because the compressed source is close to unreadable, Camping ships camping-unabridged.rb - the same framework, fully commented and documented, at around 34 KB - alongside the roughly 5 KB camping.rb that actually gets loaded. A Rake task checks that the two remain equivalent. It is an unusual and rather elegant answer to the obvious objection that golfed code cannot be maintained.
One file, then more files. Camping never claimed a single file was the end state. The README frames it as a starting point: begin in one file, move things out as the application grows. Rails compatibility of concepts was deliberate, so that graduating from Camping to Rails involved rearranging code rather than relearning the shape of a web application.
Whimsy is load-bearing. The naming is not incidental decoration. Applications are camps; plugins are gear, added with the gear method; the startup directory is kindling; the logging wrapper is Firewatch; the exception handler is CampGuide. This is the same sensibility that produced Why’s (Poignant) Guide to Ruby, and it is a substantial part of why the project attracted maintainers willing to keep it alive for twenty years without a commercial sponsor.
Key Features
An application in one file
The canonical Camping skeleton, from the project’s own README:
| |
Camping.goes :Blog is the hinge. It creates the Blog module and populates it with fresh copies of Models, Controllers, Views and the framework’s base classes, so that several independent Camping applications can coexist in one Ruby process without colliding.
Routing by class name, or by pattern
By default a controller’s route is derived from its class name - Index handles /, Info handles /info - and HTTP verbs map to instance methods, so def get handles GET and def post handles POST. For anything more structured, the R method builds a controller class bound to explicit patterns:
| |
Captured groups arrive as method arguments. The R helper works in reverse too - given a controller and arguments, it generates the URL - so links in views stay in sync with routes. Camping 3.x reportedly added Sinatra-style routing helpers alongside this original scheme.
Views written in Ruby
Camping’s views are Ruby methods, not templates. h1 post.title emits an <h1>; nesting is done with blocks. This comes from Markaby (“markup as Ruby”), another _why project, which Camping carries as the mab gem. It is compact to the point of being startling the first time you see it, and it means views are ordinary Ruby with ordinary Ruby control flow.
Since 2.1, this is no longer mandatory: Tilt integration lets views be written in ERB, Haml or any other Tilt-supported engine, with Markaby-style methods remaining the default.
Persistence, unbundled
Camping 1.x expected ActiveRecord, though from 1.5 it only loaded it if you referenced Models::Base. Camping 3.0 removed the ActiveRecord dependency entirely in favour of a looser arrangement in which you bring your own database layer; 3.2.6 added a Model::Base stub for use with Sequel. For a framework this size, staying out of the persistence business is the only tenable position.
Evolution
| Version | Date | What changed |
|---|---|---|
| 1.0 | January 2006 | Initial release; announced on RedHanded |
| 1.2 | January 23, 2006 | Camping.goes, file uploads, the R route helper |
| 1.4 | April 11, 2006 | Sessions, WEBrick and Mongrel handlers, URL helper |
| 1.5 | October 3, 2006 | ActiveRecord made optional/autoloaded; console mode; FastCGI directory server |
| 1.6 | never released | Markaby made optional; r404/r500/r501 error hooks |
| 2.0 | April 9, 2010 | Rebuilt on Rack; middleware support; cookie sessions |
| 2.1 | August 19, 2010 | Tilt templates; Camping.options; Ruby 1.9 support |
| 2.1.532 | March 21, 2013 | Last release before a nine-year gap (2013-2022) |
| 2.2 | never released | ActiveRecord 6.1 migrations, deprecation cleanup |
| 2.3 | July 28, 2022 | gear plugin system; multiple apps restored; size limit raised to 5,120 bytes |
| 3.0 | March 2023 (gem April 18, 2023) | Modern Rack/Rackup; ActiveRecord removed; camping new generator; KDL config |
| 3.1 | June 22, 2023 | Zeitwerk autoloading; reloader rewritten for nested app directories |
| 3.2.6 | August 9, 2024 | Falcon as default server; logging gear; current release |
The shape of that table is the story. Camping had an intense first year under its author, a productive community rework in 2010, then went effectively dormant from 2013 to 2022 - a stretch long enough that most listings still describe it as an abandoned curiosity. The 2022-2024 revival, driven largely by Karl Oscar Weber with Magnus Holm’s earlier work as the base, brought it onto modern Rack, modern Ruby (3.2.6 requires Ruby 3.1.2 or newer) and a modern project layout, without abandoning the single-file mode or the byte limit that defines it.
Running Camping Today
There is no official Docker image, which is why the Docker section of this page is empty; Camping is distributed as a gem.
| |
The 3.x generator produces a conventional project directory rather than a single script, and the current release bundles Falcon as its default server. Running a classic single-file Camping app - the examples/blog.rb in the repository, for instance - still works, which is a reasonable claim for a framework whose file format has survived three major versions.
Anyone running an application written against Camping 1.x should expect real work to upgrade: 2.0 moved the whole framework onto Rack and changed the session model, and 3.0 removed the ActiveRecord assumption that most 1.x applications were built on.
Current Relevance
Camping is a niche framework and always was. Cumulative RubyGems downloads across all versions are approximately 138,000 as of July 2026 - a rounding error next to Rails or Sinatra - and the GitHub repository sits at under a thousand stars. Nobody is building a startup on it.
What it has instead is unusual persistence. Twenty years after the first release, and seventeen years after its author walked away, Camping is still getting releases, still has maintainers, still has a book in its repository and a chat channel with people in it. Very few frameworks of any size survive the loss of their creator; almost none survive it by two decades while remaining recognisably the same thing.
Its practical audience today is roughly what it was in 2006: people who want a small web application - an internal tool, a wiki, a webhook receiver, a personal site - without the ceremony of a full framework, and who enjoy the fact that they could read the entire framework over a coffee if they wanted to.
Why It Matters
It made the microframework a category in Ruby. Before Camping, the Ruby web conversation was Rails and a handful of larger alternatives. Camping demonstrated that a real MVC stack could fit in a file, and Sinatra is widely reported to have begun as an attempt to take Camping further without becoming Rails. Sinatra in turn became a reference point for small route-block web frameworks well beyond Ruby, though the lines of influence between Sinatra and later frameworks in other languages are more often asserted than documented. Camping is the ancestor most of them have never heard of.
It is a rare readable framework. Web frameworks are normally opaque to their users - hundreds of files, layers of indirection, magic you take on trust. Camping’s dual source, with the documented 34 KB version and the compressed 5 KB version checked against each other, means the entire request lifecycle is available to be read straight through. For anyone who has wondered what a framework actually does between the socket and the controller method, it is one of the best available texts.
It is evidence that constraints produce design. The byte limit forced Camping’s contributors to make an explicit tradeoff on every single feature for two decades. The result is a framework with almost no speculative generality in it, and a set of ideas - route generation that works in both directions, applications as namespaces you can mount several of, views as plain methods - that are sharper than they would have been with unlimited room.
And it is a piece of Ruby’s cultural history. Camping belongs to a period when Ruby’s most influential figure was an anonymous author publishing cartoon-illustrated books and libraries named after camping gear, and when the language’s identity was built as much on delight as on productivity. The framework outlived its author’s public existence because the people who found it charming refused to let it die. That is not the usual reason software survives, and it is worth noticing that it worked.
Sources
- camping/camping on GitHub - README, CHANGELOG, Rakefile and gemspec
- Camping, a Microframework - project site and The Camping Book
- camping on RubyGems - release dates and version history
- RedHanded: Camping is a Microframework - _why’s January 2006 announcement
- RedHanded: Junebug, A Nice Little Wiki
- Err the Blog: Cheat! - the original Camping-backed cheat sheet service
- Sinatra (software) - Wikipedia - Sinatra’s release history and its place among Ruby microframeworks
- What we can learn from “_why”, the long lost open source developer - GitHub ReadME Project
Timeline
Notable Uses & Legacy
Sinatra
Sinatra, begun by Blake Mizerany around 2006 and first released publicly in September 2007, is widely reported to have been inspired by Camping - the idea being to take Camping's small-framework approach a little further without growing as large as Rails. Sinatra went on to become the default small Ruby web framework, which makes Camping's most consequential descendant a framework rather than an application.
Junebug
A minimalist wiki built on Camping with a SQLite backend, packaged as the junebug-wiki gem. Running it produced a self-contained folder holding the database, uploaded images and the start/stop script - the clearest demonstration of Camping's pitch that a whole web application can be something you copy around like a file.
Cheat (cheat.errtheblog.com)
Chris Wanstrath's command-line cheat-sheet service, announced on Err the Blog in 2006, was originally backed by a small Camping wiki with a YAML store; the cheat gem simply fetched sheets from it. The service is no longer online, but its Camping era is a well-documented example of a real, publicly used service on the framework.
Reststop
A community library adding RESTful resource routing on top of Camping controllers, distributed as its own gem. It is representative of the small ecosystem of add-ons and meta-packages that reportedly grew around a framework deliberately too small to include such features itself.
The Camping Book and the framework's own source
Camping's distribution ships two copies of itself: camping-unabridged.rb, a fully documented roughly 34 KB version, and camping.rb, the compressed roughly 5 KB mural generated from it, with a Rake task that verifies the two are semantically equal. The pair, together with The Camping Book chapters in the repository, has been used for years as a teaching text for reading a complete web framework end to end.