Ecto is a modern template consolidation engine that provides a unified interface for working with multiple popular template engines (EJS, Markdown, Pug, Nunjucks, Mustache, Handlebars, and Liquid).
- Purpose: Simplify template rendering by providing a single API for multiple template engines with automatic engine selection based on file extensions
- Architecture: TypeScript library with a plugin architecture -
Ectocoordinates engines,BaseEngineprovides common functionality, individual engine classes handle specific template formats - Key Dependencies:
ejs,pug,nunjucks,liquidjs,@jaredwray/fumanchu(Handlebars/Mustache),writr(Markdown),cacheable(caching),hookified(events/hooks)
- Use
pnpminstead ofnpmfor all package management commands pnpm build- Build TypeScript to ESM with type declarationspnpm test- Run linting and tests with coveragepnpm lint- Run Biome linter with auto-fixpnpm clean- Remove dist, coverage, node_modules, and lock files
- Always run
pnpm testto verify tests pass before completing changes - All new code must have corresponding tests
- Follow existing code patterns in
src/ecto.tsfor the main class - Use Biome for linting and formatting (configured in the project)
- TypeScript strict mode is enabled
src/ecto.ts- Main Ecto class (core engine coordinator)src/base-engine.ts- Base class for all enginessrc/engine-interface.ts- TypeScript interface for engine implementationssrc/engine-map.ts- Manages file extension to engine mappingssrc/engines/- Individual engine implementations (ejs, handlebars, liquid, markdown, nunjucks, pug)test/- Vitest test files
.ejs→ EJS.md,.markdown→ Markdown.pug,.jade→ Pug.njk→ Nunjucks.mustache→ Mustache.handlebars,.hbs,.hjs→ Handlebars.liquid→ Liquid
- Async and sync rendering methods are available (
render/renderSync,renderFromFile/renderFromFileSync) - FrontMatter support is built-in for Markdown files
- Caching is available via the
cacheablelibrary for performance optimization - Hooks system allows intercepting and modifying data during rendering
- Custom engines can be created by implementing the
EngineInterface