frontend-mini-challenges: the same exercise in four frameworks
Collection of frontend challenges for learning and interviews
At a glance
- What is it?
- A monorepo of small frontend interview exercises, each one solved in vanilla JavaScript, React, Vue and Angular side by side, with a Docker path for people who would rather not install Node 24.
- Who is it for?
- The unusual thing about this repository is that it is an answer key that is also a playground. Solving the same exercise four times in vanilla JavaScript, React, Vue and Angular turns each exercise into a comparison, which is how interview preparation usually gets done badly, from memory.
- 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 16 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 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why one exercise appears four times
The About section says the repository lists popular frontend challenges recommended for learning and interviews, solved in vanilla JavaScript, React and VueJs, and that you can both play with the UI and view the solutions. The About section also links an Angular solutions directory, so the prose and the file layout disagree slightly on how many frameworks are covered.
Both facts are true at once and they are worth stating separately. Four framework directories exist under `apps/`, and the Angular link is present, so Angular solutions are in the repository. The sentence that describes the coverage lists three. A reader who trusts the sentence will skip a quarter of the material, so the directory links are the more reliable of the two.
The four paths are `apps/javascript/src/challenges`, `apps/react/src/challenges`, `apps/vue/src/challenges` and `apps/angular/src/app/challenges`. The Angular path carries the `app` segment because that is where Angular projects keep their code, which is a small signal that these are real framework applications rather than hand-written mock folders. Each challenge is a working component in the idioms of its framework, so a reader comparing them sees how the same requirement looks as a vanilla DOM manipulation, as a component with state, as a reactive template and as a service plus component pair.
That comparison is the actual product here. A challenge repository that only solved things once would be a snippet collection. Solving each one four times makes the framework boundary visible: where state lives, what re-renders, what the template language assumes.
An Nx workspace named @fmc/main
The root `package.json` is called `@fmc/main`, marked private, version 1.0.0, and declares npm workspaces for `apps/*` and `shared/*`. The build tooling is Nx, at `^23.1.2`, with `@nx/js` alongside it. TypeScript is pinned at `~6.0.3`, Playwright at `^1.62.1`, Prettier at `^3.9.6`, and Husky at `^9.1.7` wired to the `prepare` script for commit hooks. The Node requirement is `^24.19.0`, which is the single most consequential number in the file.
The scripts are the interesting part, because they explain what the monorepo is actually for:
npm run dev
npm run build
npm run lint
npm run unit:test
npm run prettifyEvery one of those is `nx run-many`, so a single command fans out across every workspace. The `dev` target caps parallelism at eight, which is how six dev servers plus overhead stay usable on one machine. `build-baseless` is a separate target, which suggests some challenges deliberately run without the shared component library, so a solution stays honest about what the framework alone can do. `copy-to-dist` is worth reading in full because it shows the deploy shape: it wipes `dist` and copies each app's own output into it, including a nested path for Angular's `dist/angular/browser`.
An `overrides` entry pins `typescript` to `$typescript`, referencing the workspace's own resolution rather than a second copy. In a monorepo that ships several framework apps, two TypeScript versions in one tree is a class of bug you avoid once, at the root, instead of in each app.
Six ports, one per app, mapped the same way locally and in Docker
Local setup is four steps: clone the repository, run `npm install`, run `npm run dev`, and visit `http://localhost:6010/`. That base port matters because everything else in the repository is built around it.
The `compose.yaml` publishes ports 6010 through 6015, six consecutive ports for the `fmc` service, and the `Dockerfile` exposes the same six before running `npm run dev` as its command. The README's Docker path is a single command from the project root:
docker-compose watch --pruneThe compose file explains why watch mode is the right default rather than a convenience. Each of the seven source directories, `apps/angular`, `apps/css`, `apps/host`, `apps/javascript`, `apps/react`, `apps/vue` and `shared`, is declared with a `sync` action into `/app`, so file edits land inside the container without a rebuild. Package manifests are handled differently, with `rebuild` actions on each `apps/*/package.json` and on the root `package.json` and `package-lock.json`. That split is the detail worth copying: source syncs, manifests rebuild.
The image is `node:24.19.0-alpine`, matching the root engines requirement exactly, so the container and your local machine agree on the runtime. The build copies `package.json` and lock files, runs `npm install` with a cache mount on `/root/.npm`, and only then copies application source. Dependency installation happens before source lands, which keeps the layer cached across code changes. The `host` app, which `copy-to-dist` treats as the root of the dist tree, is the site you actually visit at 6010.
What is actually in the repository beyond the challenges
The tree shows the shape of a serious frontend project more than it shows a challenge collection. There is a `shared/` directory, and the Dockerfile copies four of its subdirectories separately: `shared/assets`, `shared/data`, `shared/styles` and `shared/components`. Components living in `shared` rather than in one framework app is what makes the four-way comparison slightly uneven, since one of the frameworks can import a component the others cannot, and that is likely what `build-baseless` exists to check.
There is also `tests/` and a separate `tests-examples/`, plus `playwright.config.ts` at the root. Two test directories with those names suggest that `tests-examples/` holds worked examples of testing patterns that the challenges themselves do not exercise, and `tests/` holds the real suite. The repository reports zero open issues, which for a project with 2414 stars and 599 forks suggests either active triage or a low complaint rate on something nobody depends on in production.
Deployment is handled by `netlify.toml`, which pairs with the GitHub Pages homepage the README advertises. A challenge site is a static output problem, and the `copy-to-dist` script exists precisely to flatten six app builds into one directory tree that a static host can serve.
Config files reveal the standards in force: `.prettierrc`, `.nvmrc`, `.npmrc`, `.deepsource.toml`, `.husky/`, a `.github/` directory and a `CODE_OF_CONDUCT.md`. Husky on prepare plus pretty-quick on staged means formatting is enforced at commit time rather than in review, which is the right place for it in a repository where many people contribute.
Who this suits, and where it stops
The honest framing is that this is interview preparation material aimed at a specific person: someone who can already write a component and wants to be able to rebuild one from a blank editor under time pressure. For that reader the value is direct. You can play with the UI, then open the solution in the framework the job actually uses, and the exercise sizes are small enough to do in a sitting.
For a beginner the repository is harder than it looks. The four-framework structure means the first thing a new contributor has to understand is an Nx workspace with six dev servers and six ports, which is a real amount of tooling to absorb before writing the first line of a solution. The README itself does not warn about this, so a reader will find out at the point where six servers start at once.
The second limit is that these are interview exercises, not production patterns. There is no router, no data fetching layer, no authentication, no accessibility audit and no state management story. Challenges like accordions, tabs, modals and drag interactions are the right size for evaluating problem solving, and the wrong size for learning what a maintained application needs.
The third limit is freshness of the answers rather than freshness of the code. With solutions in four frameworks, at least one is expressing the current idiomatic version of its framework, and the others may reflect what was idiomatic when they were written. The repository was last pushed on 2026-09-26 and is not archived, so the newest solution is recent, and the oldest is only as current as its last edit.
Reading the repo as documentation of its own tooling choices
There is a second reading of this repository worth offering to anyone maintaining frontend tooling rather than practising it. The challenge apps are small, but the infrastructure around them is the part that took decisions. Six ports rather than one app with six routes. Per-app Nx targets so `run-many` can fan out with a parallelism cap. Compose `sync` for source and `rebuild` for manifests. A `copy-to-dist` that knows Angular nests its browser build one level deeper than everyone else. A `build-baseless` target to keep the shared library honest.
Each of those choices answers a question a small project usually answers badly. Shared state across apps becomes a shared directory that at least one app can cheat with. Hot reload in Docker becomes a full rebuild loop. Deploying six builds becomes an implicit directory convention that breaks the first time a framework changes its output layout.
The `.env`, `.env.local`, `.dockerignore` and `.npmrc` files at the root suggest the setup is tuned for the author's machine, which is a fair assumption for a personal learning repository but worth knowing if you are the second person on it.
The README points contributors at `CONTRIBUTING.md` for anything beyond that, and lists two maintainers plus a contributor graph. GitHub reports zero open issues and 599 forks, so the shape of interest is people copying challenges out rather than people depending on the workspace, which is exactly what this repository is built to support.
Editorial conclusion
The unusual thing about this repository is that it is an answer key that is also a playground. Solving the same exercise four times in vanilla JavaScript, React, Vue and Angular turns each exercise into a comparison, which is how interview preparation usually gets done badly, from memory. The Nx workspace, the six reserved ports and the Docker watch mode are real engineering around what is otherwise a folder of small widgets, and the parts that will cost you time are the same parts that cost the author time: a full install and six dev servers. Start at http://localhost:6010/ and read one challenge in two languages before deciding whether the four-way comparison is what you need.
Frequently asked questions
How can I prepare for a frontend interview?
Work through the challenge directories in the framework your target role uses, starting with apps/javascript/src/challenges if you want the dependency-free version. The exercises are deliberately small, and solving the same one in a second framework is where the comparison becomes useful rather than repetitive.
Which frameworks does frontend-mini-challenges provide solutions for?
Four directories exist under apps/, covering JavaScript, React, Vue and Angular, and the README links an Angular solutions path under apps/angular/src/app/challenges. The About section names only vanilla JavaScript, React and Vue, so trust the directory links rather than the sentence.
What does frontend-mini-challenges need to run locally?
Node matching the ^24.19.0 engine requirement, then npm install and npm run dev, which fans out across workspaces with Nx and starts the apps on ports 6010 through 6015. A Docker path exists as well, using docker-compose watch --prune from the project root.
Do I need Docker to work on the challenges?
No. Docker is presented as an alternative for people who already have it installed. The documented local route is cloning the repository, running npm install, running npm run dev, and opening http://localhost:6010/.
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/sadanandpai-frontend-mini-challenges)