Library / SDK
laststance/react-typescript-todomvc-2022 avatar
laststance/react-typescript-todomvc-2022

react-typescript-todomvc-2022 is a learning project that has not decided what to become

React TypeScript TodoMVC 2022

540 stars120 forksTypeScriptMIT

At a glance

What is it?
The React TypeScript TodoMVC 2022 repository is a worked example of a modern React stack, from Vite and Recoil to Cypress and Netlify, kept by one developer who says in the project notes that he might renew it. It suits React learners and people who want a reference stack, and it is a single-author project with a stated uncertainty about its own future.
Who is it for?
The project is worth reading if you are learning React in TypeScript and want one repository where the build, the lint rules, the state layer, the component tests and the end-to-end tests are all wired together, because the six GitHub Actions workflows and the shared ESLint configuration make the toolchain itself part of the lesson.
Can I use it commercially?
Yes. MIT 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 11 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The author says up front that the project may be rewritten

The first thing in the project page is not a feature list but a status note from the author, dated Aug 16 2023, and it is the most important paragraph in the repository. He says he is considering continuing to update it as a client side SPA or rewriting the app with Server Components, and he is careful to say that Server Components do not mean the client side SPA is obsolete, since both architectures are great options depending on the application type, the dev team type and each developer's skillset. He says keeping both updated is his ideal vision unless there is plenty of rest time. He also says that he thinks TodoMVC was outdated for current JS frameworks and that he wants to renew the project about this winter. That is an unusually candid statement of intent from a repository owner, and it tells you two things about how to use this code. The stack choices are current enough to be worth learning from, and the project itself is not a commitment to a long-term maintenance window, so treat it as a reference implementation rather than a dependency.

The goal was a TodoMVC sample written in current React style

The stated purpose is narrow and specific. The project was started with the goal of continuing to publish TodoMVC apps in the latest React writing style, and the reasoning given is that when you find React on the TodoMVC top page you may first see classic style `React.createClass()` based source. The author does not complain about that, since the old-style codebase React app works all over the world and helps people in almost every case, and there is no value in spending time rewriting the new syntax sugar of a huge codebase. The aim is instead to assist new React learners and those who have not written React for a long time, by providing a handy resource for learning the latest React. The reference to TodoMVC itself matters for the reason given in the status note: it is a specification of a small application, and this repository is one answer to that specification written in a current stack. The application itself, a todo list with filtering and persistence, is deliberately trivial so that everything interesting is in the structure around it.

A Vite and Recoil stack with styled-components and React Router

The stack list is the substance of the project, and the choices are modern but not bleeding edge. The build tool is Vite, the language is TypeScript at v4.2.4, routing is React Router, styling is styled-components for CSS-in-JS with stylis as the companion library, and state is Recoil, described as a state management library for React. The package manifest confirms the pinned versions, with react and react-dom at 18.2.0, react-router-dom at 6.18.0, recoil at 0.7.7, styled-components at 6.1.1 and stylis at 4.3.0. The HTML and CSS come from the TODO-CSS-Template project by Klerith, with the author asking for thanks. Two details are worth noticing. First, the TypeScript version in the stack list is much older than the tooling around it, with ESLint at 8.53.0 and the TypeScript ESLint packages at 6.10.0, so a reader copying the configuration will be copying a 2022 snapshot rather than today's advice. Second, the browserslist field in the manifest is explicit about targets, with production at greater than 0.2 percent, not dead and not op_mini all, and development pinned to the last version of Chrome, Firefox and Safari. That field is where a Vite project decides its build output, and it is the first thing to check when you repurpose this code.

Getting it running is degit, pnpm, install, start

The setup path is a sequence of four commands, and the project notes are explicit about the Node requirement first: the app assumes you have installed `Node.js` newer than v18.16.1 LTS, and points at the official Node documentation if you do not. The project is fetched with degit rather than cloned, so the history does not come with it:

bash
npx degit laststance/react-typescript-todomvc-2022 react-typescript-todomvc-2022

Then you change into the directory, install pnpm globally and use it for the install and the start:

bash
cd react-typescript-todomvc-2022
bash
npm -g pnpm
bash
pnpm i
bash
pnpm start

The result is that the todo app launches on your default browser and the code is ready to edit. The package manager choice is deliberate rather than incidental, since the repository ships a `pnpm-lock.yaml` rather than a yarn lockfile, and the project notes explain that you can do the exact same thing with npm or install yarn if you prefer. A lockfile plus a chosen package manager is a detail learners often skip and teams never should.

The command surface covers lint, typecheck, unit tests, Cypress and cleanup

The project notes document the command set in a way that doubles as a lesson in what a project of this size should have. `yarn install` pulls all the node package modules the project depends on. `yarn start` runs the dev server and prints server process messages, and the instruction is to follow the message and put `http://localhost:3000/` in the browser address bar, then modify whatever is under the `src/` code. `yarn build` produces a production build with the bundled optimization stuff in the `build` directory, and `yarn serve` runs that production build. `yarn lint` runs ESLint at the top, with TypeScript ESLint set up and Prettier integrated as an eslint-plugin-prettier, using a shared config named eslint-config-typescript-react-pro that is published separately by the same author. `yarn lint:fix` runs the eslint fix option, which the documentation says is frequently used to perform Prettier formatting. `yarn typecheck` checks TypeScript errors across the whole project, and `yarn test` runs Jest with react-testing-library for component integration testing. `yarn clean` deletes `node_modules/*`, `yarn.lock` and `build/*` at once, and `yarn prettier` runs Prettier formatting over the whole project.

Cypress is the end-to-end layer, and it needs the dev server running

End-to-end testing is where this repository does more than the minimum, and the setup detail is the useful part. `yarn cypress:open` opens the Cypress runner, which the documentation describes as an all-in-one E2E testing tool that can deal with testing on a real browser, using Electron by Cypress default. It has a hard requirement that is easy to miss: `yarn cypress:open` requires `yarn start` before. The two commands are shown together:

bash
yarn start # Launch DevServer
yarn cypress:open

`yarn cypress:run` runs the same tests headlessly with Electron, and the documentation notes it is the same as running them all. The layering is worth naming because it explains the dependency choices. The dev server is the Cypress target, so the end-to-end tests run against the same app a developer sees, and the unit and integration layer underneath uses Jest and react-testing-library instead, which is a much faster loop for the component-level assertions. On top of that sits Percy, which the repository says it uses for visual regression testing, with a badge confirming it, and the manifest carries the percy cli and percy cypress packages along with the testing-library cypress bindings. The combination of three test layers in one example is the most transferable part of the project.

Six workflows and a shared lint config make the toolchain the project

The badge row at the top of the project page is really a list of the repository's own continuous integration, and it names five separate workflows for a todo application. There is a build workflow, an end-to-end workflow for Cypress, a lint workflow, a test workflow, and a typecheck workflow, each with its own badge. On top of that GitHub Actions is described as the automation that runs tests, lint, typecheck and build. The point of splitting them is not redundancy, it is that a failure tells you which kind of problem you have before you look at any code, and a type error is caught by a different job than an end-to-end failure. The lint setup is similarly consolidated into a shared config, eslint-config-typescript-react-pro, published as its own repository, which the project notes link along with the explicit all-rule-set list. The manifest shows what that means in practice, with eslint-plugin-jsx-a11y for accessibility rules, eslint-plugin-import for import ordering, eslint-config-prettier to turn off the rules Prettier already handles, and eslint-config-ts-prefixer for TypeScript import prefixing. Deploy and hosting go to Netlify with a deploy status badge, and Depfu is there to keep npm packages automatically up to date.

Where this example is the wrong starting point

Two things stand out if you plan to build on it. The first is Recoil. The state layer is pinned at 0.7.7, and the release history shows a project tagged on 2020-10-08 named Migrate @laststance/use-app-state to Recoil, which tells you the author was already replacing one state library with another. The author's own status note says he may rewrite the app with Server Components, and while he is careful to say that client side SPAs are not obsolete, the direction of travel he describes would replace the part of this codebase that a learner would most want to study. Adopting a state layer that the maintainer is considering replacing is a poor foundation for a long-lived application. The second is that the project has no test coverage claim and no stated production intent, and the project itself frames the deliverable as a learning resource rather than a starting point. The alternative to weigh against is building the same application from the current React documentation yourself, which takes longer and teaches less about tooling. The real alternative for a production team is any current TypeScript React template with a maintained state library, where the difference in approach is that the state choice is one the maintainers still support rather than one scheduled for rewrite.

Editorial conclusion

The project is worth reading if you are learning React in TypeScript and want one repository where the build, the lint rules, the state layer, the component tests and the end-to-end tests are all wired together, because the six GitHub Actions workflows and the shared ESLint configuration make the toolchain itself part of the lesson. It is a poor fit as a starting point for a production application, since the state layer is Recoil at version 0.7.7 and the author says in the project notes that he is considering a rewrite with Server Components, which is an invitation to rewrite rather than a foundation to build on. Before you adopt any of it, read the project status note at the top of the project page rather than the feature list, check that the pinned TypeScript 4.2.4 and the browserslist targets still match your own toolchain, and note that the last push to the repository was on 2026-10-12 with the only tagged release being v1.0.0 from 2022-06-25.

Frequently asked questions

How do I run react-typescript-todomvc-2022 locally?

You need Node.js newer than v18.16.1 LTS, then fetch the project with npx degit laststance/react-typescript-todomvc-2022 react-typescript-todomvc-2022, change into the directory, install pnpm with npm -g pnpm, and run pnpm i followed by pnpm start. The app then launches on your default browser and the code under src/ is ready to edit.

Which state management library does react-typescript-todomvc-2022 use?

It uses Recoil, pinned at 0.7.7 in the package manifest and described as a state management library for React. The release history includes a 2020 tag named Migrate @laststance/use-app-state to Recoil, showing an earlier state library was replaced.

How does the project run end-to-end tests with Cypress?

yarn cypress:open opens the Cypress runner, which uses Electron by default, and it requires yarn start to be running first because the dev server is the test target. yarn cypress:run runs the same suite headlessly, and the project also uses Percy for visual regression testing.

Is react-typescript-todomvc-2022 still being maintained?

The author says, in a note dated Aug 16 2023, that he is considering continuing the project as a client side SPA or rewriting it with Server Components, and that he wants to renew the project. The last push to the repository was on 2026-10-12, and the only tagged release is v1.0.0 from 2022-06-25.

Official sources

  1. laststance/react-typescript-todomvc-2022 on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/laststance-react-typescript-todomvc-2022.svg)](https://hysenlabs.com/projects/laststance-react-typescript-todomvc-2022)

Was this useful?