vanilla-todo is a case study, not a framework, and it says so
A case study on viable techniques for vanilla web development.
At a glance
- What is it?
- vanilla-todo is a clone of a to-do application written in plain HTML, CSS and JavaScript with no build steps and no runtime dependencies, published as a case study on what vanilla web development costs and where it works. Its own conclusion is that the approach is maintainable but verbose and duplicated, and that it validates the value of build steps and frameworks while also identifying the few areas where vanilla is clearly inferior.
- Who is it for?
- vanilla-todo is worth reading if you have ever argued about whether a framework is needed, because it is the rare attempt to settle the argument with a real application and an honest scorecard, and its verdict is closer to the middle than either side usually wants.
- Can I use it commercially?
- Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 82 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The motivation is research, not evangelism
The stated motivation is that too little has been invested in researching practical, scalable methods for building web applications without third party dependencies, and the author is careful about what is missing. It is not enough to describe how to create DOM nodes or how to toggle a class without a framework, and it is rather harmful to write an article saying you do not need library X and then proceed to describe how to roll your own untested, inferior version of X. What is missing, in the author's view, are thorough examples of complex web applications built only with standard web technologies, covering as many aspects of the development process as possible. That framing matters for how to read the rest, because the project is not proposing a way to work, it is a measurement, and it is a measurement of a specific application against specific criteria, with the results published whether or not they flatter the approach.
Five rules, and the one that does most of the work
The method is stated in four steps, pick an interesting subject, implement it using only standard web technologies, document the techniques and patterns found during the process, and assess the results by common quality standards. The rules that constrain the implementation are five. Only standard web technologies. Only widely supported JavaScript features unless they can be polyfilled, with the note that this is a moving target and the current version uses ES2020. No runtime JavaScript dependencies, except polyfills. No build steps. And no general-purpose utility functions related to the DOM and UI, with the parenthetical explanation that those usually end up becoming a custom micro-framework, which would question why you did not use an established and tested library in the first place. That last rule is the sharpest one, because it is the rule that forbids the shortcut most vanilla experiments take, which is to write a small helper library and then call the result vanilla.
The subject is a to-do app with drag and drop
The subject is a functionally reduced clone of TeuxDeux, chosen because the user interface has interesting challenges, in particular performant drag and drop when combined with animations. The author is explicit that the original deserves praise and calls its overall concept and user experience the best of all the to-do apps, and that the interface is arguably small, which is good for a case study, but large enough to require thought on its architecture. The areas the implementation is said to lack are listed too, and they are the interesting ones for a study of this kind, since they are exactly what a framework usually supplies: routing, asynchronous resource requests, complex forms and server-side rendering. The consequence is that the study is not a defence of the original, it is an investigation of what a vanilla implementation has to supply itself in those places.
rscss for the HTML, CSS variables, and an unaddressed namespace problem
Since build steps are ruled out, the codebase is plain HTML, CSS and JavaScript files, and the HTML and CSS follow the rscss convention, which gives an intuitive, component-oriented structure without a preprocessor. The author is candid about the cost. The stylesheets are slightly verbose, CSS variables did help, but the author missed SCSS here and thinks it is a must-have for bigger projects, and the global CSS namespace problem is unaddressed, with CSS Modules given as the example of what handles it. That last point is the interesting omission to notice, because a build-step-free project cannot use CSS Modules without a bundler, and the naming scheme that rscss provides is a convention rather than a mechanism, so the collision risk is real and the README says so instead of hiding it. The JavaScript side is all ES modules with import and export, and the code carries JSDoc comments, which is how a plain JavaScript project gets editor assistance without a type checker in the build.
Mount functions, data flow, rendering and reconciliation
The implementation chapter is organised around four ideas, and the table of contents names them because they are the reusable parts. Mount functions are the pattern the author calls minimum viable, and the whole architecture section exists to describe them. Data flow covers how state moves through the application. Rendering covers turning state into DOM. And reconciliation covers the problem that a framework usually solves, keeping the DOM in step with the state, and it is listed as a separate section because that is where the vanilla approach has to do the work itself. Elsewhere in the same chapter there is a section on drag and drop and one on animations, which are the two features of the subject that forced the architecture to be interesting in the first place. The project also publishes the source in a public/ directory and encourages readers to inspect it alongside the text, which is the right instruction for a case study, since the argument is in the code as much as in the prose.
Tooling, and how a no-build project gets a dev server anyway
The tooling chapter is where the no-build-step rule gets interesting, because a development server, a linter, a formatter and a test runner are all build tooling in some sense. The package.json shows how it is done. The dev script runs a static server with SPA fallback, s4d public --spa, the format and format-check scripts run prettier, the lint script runs eslint, lint-styles runs stylelint over the stylesheet directory, and the test script runs playwright test with the Chromium project only, with test-e2e running the full playwright set, test-ui running the Playwright UI mode, and test-coverage running a shell script. The dev dependency set is entirely tooling, with playwright, c8 for coverage, eslint with eslint-plugin-compat, prettier, stylelint and s4d, and there is no runtime dependency at all, which is the rule honoured literally. The compatibility angle is handled with the eslint-plugin-compat plugin and a browserslist configuration of defaults with op_mini all excluded, and there is an es5/ directory in the tree for a legacy build, so the support question is answered rather than assumed.
The verdict: maintainable, verbose, and worse in a few places
The assessment chapter is the point of the whole case study, and the summary in the README gives the finding. The result is maintainable, albeit verbose and with considerable duplication, and the author says that if anything the case study validates the value of build steps and frameworks while also demonstrating that standard web technologies can be used effectively and that there are only a few critical areas where a vanilla approach is clearly inferior. The three assessment axes are user experience, code quality and generality of patterns, and the headline numbers are about the user experience, 50 percent less time to load and 95 percent less bandwidth in this case, for a total transfer size of 55 KB unminified, running smoothly at 60 FPS. The conclusion chapter is a summary, and the beyond-vanilla chapter points at Vanilla Prime, a practical guide to almost-vanilla web development based on the insights from this case study. The first version of the study was published in 2020 and has been updated since, and the README asks for an intermediate understanding of the web platform to follow it.
Editorial conclusion
vanilla-todo is worth reading if you have ever argued about whether a framework is needed, because it is the rare attempt to settle the argument with a real application and an honest scorecard, and its verdict is closer to the middle than either side usually wants. It is the wrong thing to copy as a starting point for a production application, because the author himself describes the result as verbose with considerable duplication and names the areas where vanilla is clearly worse. Before you take anything from it, read the assessment section rather than the implementation, decide which of the three assessments, user experience, code quality or generality of patterns, is the one you care about, and look at the es5/ directory and the browserslist configuration to see how the project handled the support question, since that is where most of the real decisions are.
Frequently asked questions
What is vanilla-todo?
It is a TeuxDeux clone in plain HTML, CSS and JavaScript with no build steps, published as a case study on viable techniques for vanilla web development. It is fully animated, runs at 60 FPS, and has a total transfer size of 55 KB unminified.
What rules did the author follow while building vanilla-todo?
Only standard web technologies, only widely supported JavaScript features unless they can be polyfilled, no runtime JavaScript dependencies except polyfills, no build steps, and no general-purpose utility functions related to the DOM and UI, since those usually end up becoming a custom micro-framework.
What did the case study conclude about vanilla web development?
The result is maintainable but verbose and with considerable duplication. The README says the study validates the value of build steps and frameworks while also showing that standard web technologies can be used effectively, with only a few critical areas where the vanilla approach is clearly inferior.
How is vanilla-todo tested and linted without a build step?
With Playwright for end-to-end tests, run per project with playwright test --project Chromium for the fast path, c8 for coverage, eslint with eslint-plugin-compat for linting, prettier for formatting, stylelint for the stylesheets, and a browserslist configuration of defaults with op_mini all excluded.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/morris-vanilla-todo)Was this useful?