# Camping: a Ruby microframework that fits on one page

> Camping is a deliberately small Ruby web microframework that keeps a whole model, view and controller application in a single file, supports several apps in one process, and extends through a plugin system. It is a good fit for small CGI-shaped services and a poor fit for anything that needs a large framework around it.

**camping/camping** — the 5k pocket full-of-gags web microframework

- Repository: https://github.com/camping/camping
- Stars: 993 · Forks: 107
- Language: Ruby
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/camping-camping

## The whole framework is meant to fit on one page

Camping's premise is size. The project describes itself as a micro web framework which stays as small as possible, and the claim is that you can probably view the complete source code on a single page. That constraint is the design, not an accident of implementation. The idea is to store a complete, if fledgling, web application in a single file the way small CGI scripts are written, but organised as a model, view and controller application, with the option of moving those three parts into separate files as the app grows. The audience is therefore two audiences at once: a Rubyist who wants a tiny web thing without a large framework in the way, and a reader who wants to see how a web stack is put together. The MIT licence and the presence of a book/ directory with chapters in the repository confirm that teaching is a first-class use, not an afterthought.

## Camping.goes :Blog defines the app namespace

An application starts by declaring a name, and everything else hangs off that name. The skeleton in the project documentation does it this way:

```ruby
require 'camping'

Camping.goes :Blog

module Blog::Models
  class Post < Base; belongs_to :user; end
  class Comment < Base; belongs_to :user; end
  class User < Base; end
end
```

Camping.goes :Blog is the entry point, and the models below it are ordinary namespaced classes. The model layer inherits from a Base class and uses a belongs_to association and a find :all style lookup, which tells you the framework expects an object relational layer underneath and does not implement one. Controllers are namespaced the same way, with a class per route whose get method fetches data and calls render. The whole MVC arrangement is visible in the file, which is exactly what makes a small app easy to hold in your head and a large app awkward to keep in one place.

## Views are Ruby methods that emit HTML blocks

The view layer is a set of methods that build markup with blocks instead of a template language, so there is no separate template syntax to learn and no separate file to open. A layout method wraps the page, and inner methods fill it:

```ruby
module Blog::Views
  def layout
    html do
      head { title "My Blog" }
      body do
        h1 "My Blog"
        self << yield
      end
    end
  end

  def index
    @posts.each do |post|
      h1 post.title
    end
  end
end
```

The html, head and body calls are method calls, and yield pulls in the rendered view inside the layout, with self << used to splice the result into the body. The controller calls render :index, so the naming ties the controller action to the view method of the same name. This is the part of the framework that will feel most alien if you come from ERB or Haml, and also the part that keeps a view in the same file as everything else instead of pushing it into a templates directory.

## Several apps can run in one process

Camping supports multiple apps, which the documentation calls capsuled code that runs together, and each app can have independent models, routes and controllers. That is a distinguishing feature rather than a detail. A process can host a small blog app and a small admin app side by side, each with its own namespace and its own routing table, without the two sharing model classes or route prefixes by accident. The tradeoff is that isolation is by convention and namespace rather than by process boundary, so a bug in one app's controller still takes down the process that hosts both. For a single tiny service that is a non-issue. For a deployment where two apps need separate failure domains, the same property that makes Camping convenient makes it the wrong tool.

## camping new Donuts scaffolds a project you can run

Installing is a gem install, and a generator does the rest of the setup:

```bash
gem install camping
```

```bash
camping new Donuts # You can replace Donuts with whatever but CamelCased.
```

The generator creates a new directory with the essentials in it, and the name is expected in CamelCase. From there the project dependencies are installed with bundler and the app is started with the camping command:

```bash
cd donuts; bundle install
```

```bash
bundle exec camping -e development
```

The project documentation asks you to prefix the command with bundle exec so the app runs against the gems installed for that project rather than the system ones, and it recommends the development environment flag locally. The tests follow the same bundler-first habit, run with bundle exec rake, and the release process is plain RubyGems, with gem build -o camping.gem followed by gem push camping.gem.

## The plugin system is the extension point, and it is small

Extension happens through a simple plugin system, described as a way to add all sorts of useful and silly things, and the repository layout backs that up. Besides lib/ and test/ there are extras/ and docs/ directories, a constants.rb file at the top level, and examples/ with a blog.rb file and a README. The constants file being a top-level entry suggests that shared constants are patched or extended from outside the core rather than edited in place, which is the usual shape for a framework that wants plugins to be able to add routes or methods without forking. The honest limitation is that no plugin catalogue, API or compatibility policy is described in the documentation, so there is no way to tell from the repository whether a given plugin will still work with the version you install.

## The Camping Omnibus is retired, and the release pace has slowed

Two things in the project documentation deserve a second look before you adopt it. The first is the Camping Omnibus, a packaged set of recommended libraries, whose line in the README is struck through with a note that it will return for summer vacation, and the repository still carries camping-omnibus.gemspec-old, so it is genuinely not shipping. That matters because a bundle of recommended libraries was the intended answer to the question of what a small framework should include, and its absence leaves that choice to you. The second is pace. The last push to the repository was on 2026-08-24, while the three most recent releases are 3.2.6 from 2024-08-09, 3.2.5 from 2024-06-14 and 3.2.4 from 2024-06-11. Recent commits and older gems is a pattern worth checking in CHANGELOG before you pin a version in production.

## Where a small framework stops being the right answer

The size of Camping is its appeal and its limit, and the failure mode is predictable. Because the whole application can live in one file, the code that organizes it can also live in one file, so a growing app turns into a long file with everything in it, and the fix, splitting models, views and controllers into separate files, is a manual refactor the framework does not perform for you. The model layer also assumes something else provides persistence, since the skeleton inherits from Base and calls belongs_to and find :all, so a real application still pulls in a database library, and the framework's own answer to that, the Omnibus, is retired. The realistic alternative to a framework this small is a stack assembled from separate pieces, where routing, persistence and templating are separate dependencies you can replace one at a time. Camping trades that replaceability for a single file you can read end to end, which is a good trade for a small service and a bad one for a system with a long life.

## Conclusion

Camping fits a developer who wants a small Ruby service, an internal tool or a teaching example where the entire request path is readable in one file, and it fits a team that values the plugin boundary over framework capability. It does not fit a project that needs a large framework's conventions, a batteries-included ORM story or an active release cadence, and the gap between the last push on 2026-08-24 and the 3.2.6 release from 2024-08-09 says to check the changelog before you depend on it. Start with camping new Donuts, run bundle exec camping -e development, and read the first chapters of The Camping Book in the book/ directory before writing your first route.

## FAQ

### How do I install Camping and start a new project?

Install the gem with gem install camping, then run the generator with a CamelCase name such as camping new Donuts. Inside the new directory, run bundle install and start the app with bundle exec camping -e development.

### What does Camping.goes :Blog do?

It declares the application and its namespace. Models, controllers and views are then written as modules under that name, such as Blog::Models and Blog::Views, and the controller calls render to invoke the matching view method.

### Can I run several Camping apps in the same process?

Yes. The documentation states that Camping supports multiple apps, capsuled code that runs together, and that each app can have independent models, routes and controllers.

### Is Camping still being released and maintained?

The last push to the repository was on 2026-08-24, while the three most recent releases are 3.2.6 from 2024-08-09, 3.2.5 from 2024-06-14 and 3.2.4 from 2024-06-11. The README describes Camping as under active development, and CHANGELOG in the repository records changes.

## Sources

- [camping/camping on GitHub](https://github.com/camping/camping)
- [Issues](https://github.com/camping/camping/issues)
- [License: MIT](https://github.com/camping/camping/blob/main/LICENSE)
- [README](https://github.com/camping/camping/blob/main/README.md)
- [Releases](https://github.com/camping/camping/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/camping-camping
