react-seed is a React enterprise template with the guardrails already wired
🌱 React Seed: A seed, infinite possibilities. React Seed 种子项目,一颗种子无限可能
At a glance
- What is it?
- guokaigdg/react-seed is a TypeScript and Vite frontend template that ships MobX stores, a centralised router with lazy loading, an axios layer, path aliases, three environment files and a full lint and commit hook setup. It saves a week of setup and hands you opinions you did not choose.
- Who is it for?
- Adopt react-seed if you are starting a React admin or enterprise dashboard in TypeScript and want routing, state, request handling, styling and commit hooks already decided, since the template wires all of it in one repository. Do not adopt it if your team wants a different state library, or if you cannot move to Node 24, because the package manifest sets the engines field to node 24.0.0 or newer and the CI pins 24.19.0 through volta.
- 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 17 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A template that fixes decisions before you open a file
react-seed is a React frontend template, described in the repository as an out-of-the-box React enterprise frontend template. The stated selling points are that it works without extra configuration, that key modules carry explanatory comments, that startup and compilation are fast, that it is easy to customise, and that it enforces a strict code standard.
What that means concretely is visible in the technology table. React and ReactDOM on 19.x, TypeScript on 6.x, Vite with `@vitejs/plugin-react` on 8.x, `react-router` on 8.x, MobX with `mobx-react-lite` on 7.x and 5.x, axios with axios-retry on 1.x, Less with CSS Modules and PostCSS, `@phosphor-icons/react` plus local svg files turned into React components through `vite-plugin-svgr`, and a linting stack of ESLint 9 in flat config, Prettier, Stylelint, husky, lint-staged and commitlint.
That list is the product. There is no library here that is hard to learn; the point is that someone has already chosen one option in each category and made it work together. For a team that has no opinion about state management or styling, that is genuinely valuable. For a team that does, it is a set of defaults to argue with.
The environment requirements are the first hard constraint. Node 24.0.0 or newer, with CI fixed to 24.19.0 through volta, and npm 7.0.0 or newer, or yarn 1.22.4 or newer, or pnpm, with one of the three package managers.
src/ split by role, not by feature
The directory layout is the clearest statement of how the project thinks. The application entry is `src/index.tsx`, the root component is `src/App.tsx` which uses `useRoutes`, and `src/vite-env.d.ts` holds the Vite type and `import.meta.env` declarations.
Then the areas are separated by technical role: `router/` holds a centralised route table built with `React.lazy` and `SuspenseLazy`, `api/` is the interface layer with an axios wrapper and a directory per page, `store/` holds the MobX stores, `components/` holds shared components exported through a single barrel, `view/` holds page-level components, `constants/` holds constants and enums, `interface/` holds business type definitions, `types/` holds global declaration files, `utils/` holds utility functions and custom hooks, `assets/` holds static resources including an svg sprite, and `styles/index.less` holds global styles.
The role-based split is a deliberate choice and it is the one most likely to conflict with your habits. Feature-first layouts, where everything for a page sits in one folder, do not map onto this tree at all. If your team works feature-first, the migration is not a rename but a reshuffle, and that reshuffle is the real cost of the template.
The `docs/` directory holds design documents, UI references and the English README, and `public/` holds a favicon that is not processed by the build.
Path aliases are mandatory, and the README says so
The template defines path aliases in both `tsconfig.json` and `vite.config.ts`, and the development guidance is explicit that the alias should be preferred over relative paths. The example given is two imports:
import {Button} from '@/components';
import {useStores} from '@/store';The fact that the alias has to be configured in two places is the kind of detail that catches people out. The TypeScript compiler needs the mapping to resolve the types, and Vite needs the same mapping to resolve the runtime import. Get one right and not the other and you get an editor that works while the build fails, or the reverse.
The `tsconfig.json` also carries the path alias, and the repository splits TypeScript configuration across `tsconfig.json`, `tsconfig.app.json` and `tsconfig.node.json`, the standard Vite arrangement where the app and the tooling, such as the Vite config itself, compile under different settings.
The development guide then gives you the three-step recipe for adding a page: create `index.tsx` and `index.less` under `src/view/XxxPage/`, register the lazy route in `src/router/index.tsx` using `SuspenseLazy`, and if you need a top navigation entry, edit `src/view/Tab/index.tsx`. Three steps, each pointing at a specific file, which is the kind of documentation that makes a template worth reading.
MobX rules that are easy to get wrong
The state management section states three rules for MobX, and they are not stylistic preferences.
The store constructor calls `makeAutoObservable(this)`, and any asynchronous assignment has to be wrapped in `runInAction(...)`. A new store is registered in the `stores` object in `src/store/index.ts`. And any component that reads an observable must be wrapped in `observer`. The last rule is stated in bold in the original text, and it is the one that bites.
The reason is that MobX tracks reads, not writes. A component that reads an observable outside an `observer` boundary will not re-render when that observable changes, so the UI silently goes stale and the usual debugging path is to stare at the store and conclude the write never happened. The `observer` wrapper is not optional in a MobX codebase, and the template takes the position that the compiler will not catch a missing one.
The `runInAction` requirement has the same character. A MobX strict mode setup will complain about mutating an observable outside an action, and the usual shape of a fix is to wrap the assignment in `runInAction` so the mutation is allowed and, in a strict setup, enforced. Wrapping only the assignments that follow an await is the pattern that catches most newcomers out.
The template also ships `AGENTS.md`, a project description aimed at AI coding assistants, and the README points readers there for the more detailed development conventions.
The API layer expects one directory per page
Adding an API call follows the same shape as adding a page. Create `src/api/<page-name>/` with an `index.ts` and a `types/<page-name>.ts`, import the wrapped `request` from `../request`, and call it as `request<ResponseT>({url, method, data})`. Request and response types live in the `types/` directory of the same folder.
The design is unremarkable and that is a point in its favour. The axios instance is configured once, in a `request` module, and every page talks to it the same way. Because the types are colocated with the call, an endpoint and its payload type change together.
The one thing to know is that axios comes with axios-retry in the dependency list, so failed requests can be retried automatically. Whether that is a good default depends entirely on the endpoint, and the template does not document a per-call opt out in what is written here. If you add an endpoint that is not idempotent, check how the retry is configured before you rely on it.
Three environment files sit at the repository root, `.env.development`, `.env.qa` and `.env.production`, and the build scripts select between them by mode, which is why there is a separate QA build target rather than a single production build.
Scripts, branches and the commit format the hooks enforce
The npm scripts are short and worth reading before anything else:
"dev": "vite",
"start": "vite",
"build:qa": "vite build --mode qa",
"build:prod": "vite build --mode production",
"preview": "vite preview",
"clean": "rm -rf node_modules",
"deploy": "npm run build:prod && gh-pages -d build"The `clean` script is `rm -rf node_modules`, which works on macOS and Linux and will not work on native Windows shells. The `deploy` script builds for production and pushes the `build` directory with gh-pages, which is how the online demo at the GitHub Pages address in the repository description is served.
Getting started is the two-step sequence the README gives, with npm or yarn as your choice:
npm install
# or
yarn installThen start the development server, which runs Vite:
npm run startThe commit rules are enforced rather than documented in passing. Husky installs a pre-commit hook running lint-staged and a commit-msg hook running commitlint with the config at `.commitlintrc.js`. lint-staged runs ESLint on TypeScript and JavaScript files, Stylelint on CSS, Less and SCSS, and Prettier in write mode across the widest set of file types, including JSON, HTML, YAML and Markdown. The commit format itself is a type, an emoji and a subject, for example `feat:` with a subject, with ten conventional types defined in the README table.
Versioning signals, licence and the gap between the tag and the manifest
The manifest says version 2.0.0 and names the package react-seed with the description an out-of-the-box React enterprise frontend template. The only GitHub release listed is v1.0.0 from 2026-05-27, and the repository is not archived, with the last push on 2026-10-06.
So the published tag and the manifest disagree, and the reasonable reading is that the project is being developed past its first tagged release without cutting a new one. If you are pinning a version, the tag is what npm would resolve to for a release install, and the manifest in the repository is a later state. That is a normal situation for a template and an annoyance if you wanted a stable point to fork from.
The licence is MIT, and the README states that the code and documentation are released under the MIT License with a link to the LICENSE file. For a template, MIT is the sensible choice: you are expected to take it, change it and ship it inside a proprietary product without attribution obligations in your codebase.
The branch model is three named branches. `main` is the main branch, `dev` is the development branch, and `deploy` is the branch used for the demo deployment. If you fork this, the deploy branch and the gh-pages script give you a way to publish a live demo of your fork, which is a nice touch for a template repository.
The dependency ranges are carets, so a fresh install picks up patch and minor updates within each major, and the browser support list in the manifest is a permissive modern baseline: greater than 0.2 percent usage, not dead, and not op_mini all.
Editorial conclusion
Adopt react-seed if you are starting a React admin or enterprise dashboard in TypeScript and want routing, state, request handling, styling and commit hooks already decided, since the template wires all of it in one repository. Do not adopt it if your team wants a different state library, or if you cannot move to Node 24, because the package manifest sets the engines field to node 24.0.0 or newer and the CI pins 24.19.0 through volta. Before you start, read AGENTS.md and the path alias setup, and confirm that the MobX rules, specifically makeAutoObservable in the constructor and observer on every component reading an observable, match how your team already writes state.
Frequently asked questions
What does guokaigdg/react-seed include out of the box?
It is a React 19 and TypeScript template on Vite with a centralised react-router table using React.lazy, MobX stores through mobx-react-lite, an axios request layer, Less with CSS Modules, path aliases, three environment files and a lint stack of ESLint 9, Prettier, Stylelint, husky, lint-staged and commitlint.
What are the Node and package manager requirements for react-seed?
Node 24.0.0 or newer, with CI fixed to 24.19.0 through volta, and npm 7.0.0 or newer, or yarn 1.22.4 or newer, or pnpm. The package manifest sets the same Node and npm floors in its engines field.
How do I add a new page and API call in react-seed?
A page goes in `src/view/XxxPage/` with an index.tsx and index.less, is registered in `src/router/index.tsx` with SuspenseLazy, and can be linked from the top navigation in `src/view/Tab/index.tsx`. An API call goes in `src/api/<page-name>/` with an index.ts and a types file, calling `request<ResponseT>({url, method, data})` from `../request`.
What are the MobX conventions in react-seed?
Store constructors call makeAutoObservable(this), asynchronous assignments are wrapped in runInAction, new stores are registered in the stores object in `src/store/index.ts`, and any component reading an observable must be wrapped in observer.
How do I build and publish the react-seed demo?
The scripts include build:qa, build:prod, preview, clean and deploy, where deploy runs the production build and then publishes the build directory with gh-pages. The deploy branch is used for the demo deployment, and the live demo is hosted on GitHub Pages.
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/guokaigdg-react-seed)Was this useful?