All projects
ShiryokuOpen sourceArchivedGitHub stars: 31

Shiryoku

Open-source curated upskilling resources.

Shiryoku

Overview

An open-source initiative to cut the friction between students and the resources they need to upskill — curated links across programming, design, and engineering, with roadmaps for working through them. Built on the idea of being the senior you needed as a junior.

Shiryoku (資料, "materials" in Japanese) is an open-source site of hand-picked learning resources, with roadmaps that put them in a sensible order. The resources cover programming, design, engineering, finance and more. You can browse them, filter by tag, or search.

It was built around one idea: be the senior you needed as a junior.

It's MIT-licensed, and anyone could add a resource, either directly on GitHub or through a form.

Why I built it

I built Shiryoku in college, around my third year, while I was learning web development. The main reason was to learn TypeScript on something bigger than a tutorial. I wanted a project I could build on my own, with real data and real structure.

Bookmarks, browser search and plenty of "best resources for X" lists already existed then. This wasn't a gap nobody had filled. It was a useful thing to build while learning, and it was also useful to hand to juniors and club members as a place to start.

Architecture

The site is a static single-page app with no backend. The content lives in typed TypeScript data files, and the UI reads it directly.

  • Data layer: resources.ts, roadmaps.ts, tags.ts and notifications.ts hold everything as typed arrays and objects.
  • State: a Redux Toolkit store holds the resources, tags, roadmaps and the current filters.
  • UI: React with Material UI and React Router. The views are the resource grid, tag filter, search, roadmaps and notifications.
  • Build and deploy: tsc && vite build, then published to GitHub Pages at resources.kunalkeshan.dev.
  • Tooling: Vitest for tests, Prettier for formatting, and Husky for git hooks.

The project started on Create React App and later moved to Vite. The app code carried across with little change. The build got faster and the setup got simpler.

Data model

Every resource is one object. Roadmaps and topics are separate, and resources point at them by id.

  • Resource: name, description, url, icon and tags. It can optionally link to roadmaps through roadmap.ids and roadmap.subTopics.
  • Tag: lowercase and space-separated, for example web development.
  • Roadmap: an id, name, description, icon and cover, plus a list of topics.
  • Topic: its id is <roadmap id>-<order>, so a topic always says which roadmap it belongs to and where it sits.
  • Notification: a small announcement object that shows site updates.

Keeping the data in TypeScript, not JSON or a CMS, meant the compiler caught mistakes in the data as well as in the code.

Open source and contributions

Adding a resource meant editing one file. There were two ways to do it:

  • On GitHub: edit src/data/resources.ts in the browser (press . for the web editor) and open a pull request. No local setup was needed.
  • Through a form: if GitHub was unfamiliar, you could send the resources in a form and I'd add them.

The rule was check whether it already exists first. The data guide documented the exact shape, and a script regenerated RESOURCES.md from the data so the repo always had a readable list. The repo carried the Hacktoberfest topic, and at its peak the collection held around 70 resources.

Challenges and insights

  • Data consistency: tags were free text, so a typo could create a new tag by accident. I fixed it with a strict format rule (lowercase, space-separated) and a single tags file.
  • Duplicates: a curated list gets worse quickly when the same resource appears twice. "Check if it exists" became the first contribution rule.
  • Low-friction contributing: most people who have a good link don't want to fork and clone. A web-editor path and a form made contributing easy, and it mattered more than any feature.
  • Content ages faster than code: the code needed very little maintenance, but links and recommendations go stale. That is the hardest part of keeping a curated list alive.

What I learned

Shiryoku was where TypeScript went from something I read about to something I used daily. Typing the data files, the store and the components showed me how much a compiler catches before the app runs. It's also where I first took a project from an empty folder to a deployed, open-source site that other people could contribute to.

If I were starting a learning project today (suggestions)

These are things I'd pick now, not a list of what the project used.

  • TypeScript in strict mode from day one.
  • Schema validation of the data files with zod, so a bad resource fails at build time and not at runtime.
  • Vite and Vitest for a fast loop. This is the setup the project moved to.
  • ESLint or Biome alongside Prettier.
  • A few Playwright tests for the core flow (search, filter, open a roadmap).
  • A link checker in CI, since broken links are what hurts a curated list most.

Timeline and outcomes

Built from August 2022 to December 2025 as a personal, open-source project. It was archived on GitHub on 25 December 2025 and is now read-only.

It did what I built it for. I learned TypeScript on it, juniors and club members used it as a starting list, and a few people contributed back. I archived it because I'm no longer maintaining the list, and a curated list that isn't maintained goes stale.

Click any screenshot to view it full size.