TAFT HAVE YOU HEARD OF THIS WEB FRAMEWORK BUSINESS
yes, sir
THEY’RE RIDDLED WITH NEEDLESS COMPLEXITY
yes, sir
THAT ISN’T SPORTING AT ALL
no, sir
BRING ME THE WEB FRAMEWORKS
I’M GOING TO PUNCH THEM MANFULLY IN THE FACE
sir, web frameworks are software, not a person
you can’t punch a web framework in the face
OH CAN’T I
TAFT, WATCH ME BECOME THE FIRST MAN TO PUNCH A WEB FRAMEWORK IN THE FACE
THEN WRITE IT DOWN
IN YOUR OFFICIAL WHITE HOUSE NOTES
“TODAY THE PRESIDENT PUNCHED A WEB FRAMEWORK IN THE FACE”
all right
“QUITE SOUNDLY TOO”
I will
“WITH AN EXCELLENT RIGHT UPPER CROSS”
yes, sir
“CAN’T PUNCH A WEB FRAMEWORK IN THE FACE”
FORSOOTH
I’M THE PRESIDENT
I CAN PUNCH ANYTHING
Apologies to Daniel Mallory Ortberg
Roosevelt is a web framework based on Express that aims to be the easiest web framework on the Node.js stack to learn and use. Suitable for building multi-page apps, static sites, or single page apps, Roosevelt is a batteries-included framework with minimal boilerplate.
The primary design goal of Roosevelt is to reduce the complexity of your code as much as possible. Teddy Roosevelt — referred to by Cracked magazine as the "the most badass President of all-time" — curtailed the abuse of monopolists, so there's no way he would ever put up with all the indecipherable layers of abstractions and other needless complexities common to other web frameworks. If Teddy were around today, he would punch over-engineered frameworks quite soundly in the face, just as he did with trusts.
So why not just use vanilla Express then?
You could! Express is wonderful. But fine-tuning the Express framework for developing serious web apps is a lot of work because it adopts a very minimalist philosophy in its defaults. If you build a vanilla Express web app yourself, you will need to manually include and configure a lot of additional modules to handle very basic things such as handling POST request bodies, file uploads, logging, security hardening, template parsing, CSS/JS preprocessing and bundling, etc. Roosevelt wires up these features for you, sets sane defaults, and more.
Roosevelt is a low jargon, minimal abstractions framework
The best libraries and frameworks exist solely to extend and improve existing tools rather than overturn them with complete replacement abstractions. As such, Roosevelt does not replace Express or hide its functionality and features behind an opaque interface like other frameworks that sit in front of Express do. When you use Roosevelt, it simply configures Express for you, adds some features, and then returns an Express app to you to do as you like with. In this way, Roosevelt is merely a progressive enhancement of Express.
Roosevelt enhances Express with
- A simple, configurable default MVC directory structure.
- Teddy HTML templates by default which are much easier to read and maintain than common alternatives. Can be configured to use any templating system that supports Express, or even PHP.
- Sass CSS preprocessing by default with support for Less and Stylus too. Minification via clean-css. Other CSS preprocessors can be used as well with a bit of extra configuration.
- Webpack fully integrated providing an easy to use interface for bundling and minifying your frontend JS. Other JS bundlers can be used as well with a bit of extra configuration.
- Automatic progressively enhancement of supported web components in your code with fallback markup that will work if JavaScript is disabled which will then be replaced with the desired web component when the JavaScript loads. Powered by progressively-enhance-web-components.
- Automatic code-reloading in development mode via nodemon for server-side changes and express-browser-reload for frontend changes.
- Automatic HTML validation in development mode for your post-server-rendered HTML powered by express-html-validator.
Roosevelt is a progressive enhancement-first framework
As mentioned briefly above, a core principle behind the design of the Roosevelt framework is promoting progressive enhancement as a best practice in building web applications. We believe progressive enhancement is the best approach not just in regards to how Roosevelt enhances Express, but also with your frontend code as well. This means most web applications should be multi-page apps, not single page apps. It also means with few exceptions you should always focus on writing HTML first, enhance it with CSS as-needed, and enhance your HTML and CSS with JS only as-needed. Avoid JS-first architectures.
Why progressive enhancement is a best practice on the frontend
The web platform was designed with three languages (HTML, CSS, and JS) intentionally: to separate concerns and to allow a subset of functionality to be guaranteed to work even if the user's browser or internet connection can't execute the full intended experience. This is distinct from the all-or-nothing approach that native apps take and is the web's greatest superpower.
To fully understand this, let's consider a couple of analogies:

HTML, CSS, and JS are kind of like a peanut M&M
- HTML is the peanut: Consumable entirely on its own regardless of whether any CSS (chocolate coating) or JS (candy coating) enhancements are added on top of it.
- CSS is the chocolate coating: Chocolate makes the peanut better, but you can eat the peanut without it.
- JS is the candy coating: The candy coating is the best way to experience a peanut M&M, but if the candy coating is missing it's still good without it.
Build escalators, not elevators
Another analogy that helps us understand progressive enhancement is thinking about the three web languages as helping us build escalators instead of elevators. When you build a JS-first web app that can't function without JS, then you're building an elevator. If the elevator fails, then it's useless. But if you build an escalator instead, then when your escalator fails, it becomes stairs. And handling the non-JS scenario is often much more important than it may seem.
Accordingly, Roosevelt's recommended best practice for building single page apps involves using Roosevelt's built-in support for Single Page Express, which allows you to build single page apps using the Express API. You can use other SPA frameworks if you like instead, but you should consider Single Page Express because it will allow you to write isomorphic (aka universal, amphibious, etc) controller and view code that can be shared verbatim on the client and the server in your app for maximum code reuse on the client and server. That means you can server-render every page in your SPA and even support the non-JS scenario with very little extra work, unlike most other SPA architectures.
We prioritize "good" when deciding between "fast, good, and cheap" and so should you
It's often said that when presented with the options of "fast, good, or cheap," you need to "pick two" — a demonstration of the classic project management triangle. But perhaps somewhat counter-intuitively, it's often best to prioritize "good" over "fast" or "cheap" whenever you can. This is because if you cut corners while developing your product to save time or money, you're often creating a technical debt situation that will cost you as much or more time and money later.
As such, the only acceptable times to lower the priority of "good" in the pursuit of "fast" or "cheap" is when you're certain the work you're doing is truly a throwaway one-off and won't need to be maintained by anybody, or when the urgency of the situation is so high that you're willing to pay off the technical debt burden later.
Likewise, just as picking "fast" or "cheap" over "good" can result in you getting none of those things in the long run, prioritizing "good" first can make it possible for you to achieve all three at the same time: "good," "fast," and "cheap" without sacrificing any of them. Achieving that software development nirvana is obviously everyone's dream, and too few ever achieve it. So how can it be done? The answer is by becoming excellent at your craft. The better you are at what you do, the faster you'll work and the less funding you'll need to get things done.

Reducing complexity as much as possible is a core component of excellent craftsmanship
If you want to get to the point in your software development journey where you can check all three boxes in the "good," "fast," or "cheap" project management triangle, you need to use tools that strip away as much needless complexity as possible so you can focus on getting work done quickly without compromising the quality of your work. This can be difficult though because the software development ecosystem is filled with merchants of complexity — people who have a vested interest in selling you on solutions that increase complexity, either because they directly profit by it or because they have some ideological attachment to a specific way of doing things that isn't based in good evidence.
The merchants of complexity are everywhere and it can be difficult to steer clear of them. They will try to convince you that the way you're doing things is unprofessional unless you adopt their preferred, often over-engineered architecture preferences. Don't listen to them. Use the most minimally viable tool at your disposal unless and until you encounter hard evidence that something more is needed. That is the best way to avoid technical debt and get high quality work done quickly.
The Roosevelt framework team endeavors to not become merchants of complexity ourselves by embracing humility and self-awareness
The most insidious thing about the "merchants of complexity" phenomenon is it seems clear the majority of people who are shilling for over-engineered solutions aren't doing it with nefarious intent. They're true believers who really do think the complexity they're selling isn't needless. We recognize that as authors of our own series of libraries and frameworks, we could potentially have our own blind spots in this regard. What if the tools we're promoting are over-engineered too? It wouldn't be the first time an author of a framework promoted it with complexity-reducing branding only to deliver a solution that is also needlessly complicated. It happens all the time.
We think the best way to avoid falling into that trap is to state our core principles clearly and live by our values. We believe reducing complexity as much as possible empowers people get the best possible work done and we live by our values by remaining constantly vigilant about our own blind spots. We encourage evidence-based discussion and debate about ways to improve our tools either by simplifying them further, or embracing needed complexity that we incorrectly regarded as needless, and we commit to going wherever the evidence leads because we are scouts, not soldiers.
Strong opinions, loosely held, expressed as code
Because we recognize that aspects of our design philosophy could be wrong, and we respect people's desires to do what they like regardless of what the evidence says is the best approach, our work is designed to be as flexible as possible. We are less interested in selling you on an ideology and more interested in building tools that you find genuinely useful regardless of how much you agree with us about our design philosophy. Even if you reject a large amount of the recommendations in our design philosophy, much of our work could still be useful to you when assembling your own stack any way you like, if you have that need or desire. Accordingly, below is a list of modules that were built and are maintained by the Roosevelt framework team, but can be used independently of Roosevelt as well.
Independent projects in the Roosevelt project family
- check-if-CSS-is-disabled: Frontend JavaScript module that can determine if CSS is disabled or if it failed to load, then take action to stop JS enhancements from applying if the CSS isn't working first.
- crossplatform-killport: Command line program to kill the process running on a given port in any operating system.
- express-browser-reload: Refresh your browser when your Express server restarts.
- express-html-validator: Automatic HTML validation middleware for Express applications.
- fallback-dependencies: Add git repo dependencies to your Node.js app from a cascading list of fallback locations.
- minify-html-attributes: Obfuscates your HTML attribute class names, IDs, and
data-*
attributes in a coordinated fashion across your HTML, CSS, and JS files. - multi-db: A thin abstraction around selected Node.js database drivers to normalize their APIs to one simplified common API. This makes it possible to write a Node.js app that supports multiple databases by configuration with minimal additional boilerplate needed per additional database.
- node-php-runner: Allows you to run PHP code in Node.js in various ways.
- progressively-enhance-web-components: Template file preprocessor for progressively enhancing web components in Node.js.
- roosevelt-logger: Intuitive, attractive logger for Node.js applications based on Winston.
- semantic-forms: A pattern library of forms based on semantic HTML enhanced with a modern UX.
- source-configs: Allows you to declaratively define a hierarchy of configuration values for your app from command line arguments, environment variables, or defaults based on a JSON schema you define within your app.
- single-page-express: A client-side implementation of the Express route API.
- teddy: Teddy is the most readable and easy to learn templating language there is!