Learningmap is an open-source tool for creating, sharing, and exploring learning pathways. It's a monorepo built with React, TypeScript, and pnpm workspaces.
- Website: https://learningmap.app
- Documentation: https://learningmap.openpatch.org
- Repository: https://github.com/openpatch/learningmap
- Maintainer: Mike Barkmin (@mikebarkmin)
This is a pnpm monorepo with multiple packages and platforms:
learningmap/
├── packages/
│ ├── learningmap/ # Core React component library
│ └── web-component/ # Web component wrapper
├── platforms/
│ └── web/ # Web application (learningmap.app)
├── docs/ # Documentation (Hyperbook)
└── scripts/ # Build and development scripts
- Language: TypeScript
- UI Framework: React 19
- Package Manager: pnpm (required - version >= 8)
- Build Tool: Vite + esbuild
- Visual Editor: ReactFlow (@xyflow/react)
- Layout Engine: ELK.js for auto-layout
- Testing: Vitest
- Documentation: Hyperbook
- Version Management: Changesets
- Code Quality: Prettier, Husky
pnpm install # Install all dependencies
pnpm build # Build all packages
pnpm test # Run tests across all packages
pnpm lint # Type-check with TypeScript
pnpm docs:dev # Start documentation dev server
pnpm dev # Watch mode for development- Always use pnpm - The project enforces pnpm usage via preinstall hook
- Build before testing - Packages depend on each other's built artifacts
- Use Changesets - For version management and changelog generation
- Follow existing patterns - Match code style and structure of existing files
Each package has its own scripts defined in its package.json:
build: Compiles TypeScript and bundles with esbuildlint: Type-checks with TypeScript (tsc --noEmit)test: Runs tests with Vitest
- Use strict TypeScript with proper type definitions
- Prefer interfaces for props and types for unions/intersections
- Export types alongside components
- No implicit
any- always define types
- Use functional components with hooks
- Prefer named exports for components
- Use TypeScript interfaces for component props
- Follow existing patterns for event handlers (e.g.,
onprefix) - Keep components focused and modular
- Components in PascalCase (e.g.,
EditorToolbar.tsx) - Utilities and helpers in camelCase (e.g.,
helper.ts,translations.ts) - Index files export public API
- Keep related code together
The project supports internationalization (i18n):
- Translations are defined in
packages/learningmap/src/translations.ts - Use the
getTranslations(language)helper - Default language is English (
en), German (de) is also supported - Always add translations for both languages when adding new strings
- Implement the feature in the appropriate package
- Add TypeScript types for all new props/interfaces
- Update translations if adding user-facing text
- Consider both editor and viewer modes
- Test in both debug and preview modes
- Update documentation if it's a public API change
The core editor (LearningMapEditor) has two modes:
- Edit Mode: Full editing capabilities with toolbar
- Preview Mode: View-only mode for testing the learner experience
Key components:
EditorToolbar: Main menu and controlsEditorDrawer: Side panel for node/edge editing- Node types:
TopicNode,TaskNode,TextNode,ImageNode - Edge types: Regular edges, completion edges, unlock edges
- CSS is bundled with components
- Use existing CSS classes and patterns
- Follow the visual design of existing components
- Test in both light and dark modes (if applicable)
- Tests are run with Vitest
- Test files should be placed alongside source files
- Currently minimal test coverage - focus on core functionality
- Run tests with
pnpm testbefore submitting PRs
Documentation is built with Hyperbook and located in the docs/ directory:
docs/book/index.md: Main documentation entrydocs/book/development.md: Development guidedocs/book/contributing.md: Contribution guidelines- Update docs when adding features that affect the public API
GitHub Actions workflows:
pull-request.yml: Runs tests and build on PRschangeset-version.yml: Manages version bumps and releasesdocs.yml: Deploys documentation
All PRs must pass:
- TypeScript type checking (
pnpm lint) - Tests (
pnpm test) - Build (
pnpm build)
- No force pushes - Git force push is disabled
- No rebase - Use merge commits for combining branches
- Minimal changes - Make the smallest possible changes to achieve goals
- Preserve working code - Don't remove or modify working code unless necessary
- Follow existing patterns - Match the style and structure of existing code
- Use ecosystem tools - Prefer pnpm scripts and package tools over manual changes
When adding new dependencies:
- Add to the appropriate package's
package.json - Use
pnpm add <package>in the package directory - Consider bundle size impact for the web component
- Prefer peer dependencies for React and related packages
- ❌ Don't use
npmoryarn- always usepnpm - ❌ Don't commit built artifacts (
dist/folders) - ❌ Don't modify
node_modulesorpnpm-lock.yamlmanually - ❌ Don't skip the build step - packages depend on each other
- ❌ Don't add tests that don't exist - follow existing test patterns
- ✅ Do run
pnpm installafter pulling changes - ✅ Do run
pnpm buildbefore running tests - ✅ Do commit your changes using the Changesets workflow
- ✅ Do test in both editor and preview modes
- Issues: Open an issue on GitHub for bugs or feature requests
- Community: Join the Matrix community at https://matrix.to/#/#openpatch:matrix.org
- Contact: Reach out to [email protected] for support
MIT License - maintained by OpenPatch (https://openpatch.org)