Seed CLISeed CLI

Template

Generate files from Eta templates.

bun add @seedcli/template

The template module uses Eta as its template engine — a TypeScript-native engine that's 3x faster than EJS with compatible syntax.

Generate a Single File

await seed.template.generate({
  template: 'component',       // Template name (resolved from templates dir)
  target: 'src/components/Button.tsx',
  props: {
    name: 'Button',
    hasStyles: true,
  },
})

The template file at templates/component.ts.eta:

import React from 'react'
<% if (it.hasStyles) { %>
import styles from './<%= it.name %>.module.css'
<% } %>

export function <%= it.name %>() {
  return <div<% if (it.hasStyles) { %> className={styles.root}<% } %>>
    <%= it.name %>
  </div>
}

Generate Options

OptionTypeDescription
templatestringTemplate name (required)
targetstringOutput file path (required)
propsRecord<string, unknown>Template variables
directorystringTemplates directory override
overwritebooleanOverwrite existing files (default: false)

Render to a File

Render a template string directly to a file:

await seed.template.render({
  source: '<%= it.name %> v<%= it.version %>',
  target: 'VERSION.txt',
  props: { name: 'My App', version: '1.0.0' },
})

Render Options

OptionTypeDescription
sourcestringTemplate string (required)
targetstringOutput file path (required)
propsRecord<string, unknown>Template variables
overwritebooleanOverwrite existing (default: false)

Render to String

Render a template and return the result without writing a file:

const result = await seed.template.renderString(
  'Hello, <%= it.name %>!',
  { name: 'World' }
)
// => 'Hello, World!'

Render a File to String

const result = await seed.template.renderFile(
  'templates/readme.md.eta',
  { projectName: 'my-app', version: '1.0.0' }
)

Scaffold a Directory

Copy and process an entire template directory:

await seed.template.directory({
  source: 'templates/project',
  target: 'my-new-project',
  props: {
    name: 'my-new-project',
    author: 'John Doe',
    useTypeScript: true,
  },
  ignore: ['node_modules/**', '.git/**'],
  rename: {
    '_package.json': 'package.json',
    '_gitignore': '.gitignore',
  },
})

Directory Options

OptionTypeDescription
sourcestringSource template directory (required)
targetstringOutput directory (required)
propsRecord<string, unknown>Template variables
overwritebooleanOverwrite existing files
ignorestring[]Glob patterns to skip
renameRecord<string, string>Rename files during copy

Files with .eta extension are processed as templates (extension is stripped). Other files are copied as-is.

Template Syntax

Eta uses a syntax similar to EJS:

SyntaxDescription
<%= it.name %>Output escaped value
<%~ it.html %>Output raw (unescaped) value
<% if (cond) { %> ... <% } %>JavaScript logic
<% for (const item of it.items) { %> ... <% } %>Loops
<%/* comment */%>Comments (not output)

All template variables are accessed via the it object:

<% for (const field of it.fields) { %>
  <%= field.name %>: <%= field.type %>;
<% } %>

On this page