Markdown Note Board
Build a note-taking web app with React and TypeScript where you write notes in Markdown and see them rendered as you type. Notes have tags, you can filter the board by tag or search text, and everything is saved in the browser automatically, so nothing is lost when you close the tab. The preview is safe: Markdown is rendered without allowing dangerous HTML, so a note can't run scripts. Saved data is checked with Zod when it's loaded, so a corrupted save never crashes the app. It's a good first TypeScript project: you'll learn typed React components, state management with hooks, localStorage, runtime validation with Zod and testing components.
- Estimate
- ~10h
- Steps
- 7
- Completed by
- 0
- Proposed by
- codeseed.app
Node.js · React · Zod
Project roadmap
- 01
Create the project
~1hInstall Node.js (LTS version) and create a React + TypeScript project with npm create vite@latest using the react-ts template. Add zod and react-markdown. Replace the default page with a two-column layout: a note list on the left and an editor on the right. Done when: npm run dev shows the empty layout.
- 02
Define the note type with Zod
~1hDefine a Zod schema for a note: id (a string), title (1 to 100 characters), body (a string), tags (an array of strings) and updatedAt (a number). Infer the TypeScript type from it with z.infer, so the type and the validation always match. Done when: the Note type is inferred from the schema and used in your components.
- 03
Create, edit and delete notes
~2hKeep the notes in state with useState (or useReducer). Add a New note button, a list showing each note's title and tags, and an editor with a title field, a tags field (comma-separated) and a textarea for the body. Editing updates the note and its updatedAt. Add a delete button that asks for confirmation. Done when: notes can be created, edited and deleted.
- 04
Show a safe Markdown preview
~1.5hRender the note's body next to or below the editor with react-markdown, which doesn't render raw HTML by default, so a note containing <script> or <img onerror> can't run code. Make links open in a new tab with rel="noopener noreferrer". Done when: headings, lists, code and links render correctly, and a note containing a <script> tag shows it as plain text without running it.
- 05
Filter by tag and search
~1.5hShow every tag in use as a clickable chip above the list; clicking one shows only notes with that tag, and clicking again removes the filter. Add a search box that matches the title and body, ignoring upper and lower case. Sort notes with the most recently updated first. Done when: tag filtering and search work together.
- 06
Save to localStorage and validate on load
~1.5hSave the notes to localStorage whenever they change (with useEffect). On startup, load them and validate them with the Zod schema using safeParse. If the data is invalid, keep the valid notes, skip the broken ones and show a small warning instead of crashing. Done when: notes survive a page reload, and manually corrupting the saved data doesn't break the app.
- 07
Write tests
~1.5hInstall Vitest and React Testing Library. Test the Zod schema with valid and invalid notes, the filter and search function, and a component test that creates a note and checks it appears in the list. Done when: npm test passes.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack