Seed CLISeed CLI

Template

Generate files from Eta templates.

npm install @seedcli/template

The standalone package exports named functions. Inside a Seed command, the same helpers are available on seed.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

import { resolve } from 'node:path'

await seed.template.generate({
  template: resolve('templates/component.ts.eta'),
  target: resolve('src/components/Button.tsx'),
  props: {
    name: 'Button',
    hasStyles: true,
  },
})

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

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

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

Generate Options

OptionTypeDescription
templatestringTemplate file path (required)
targetstringAbsolute output file path (required)
propsRecord<string, unknown>Template variables
directorystringCurrently ignored by generate()
overwritebooleanOverwrite existing files (default: false)

Render to a File

Render a template string directly to a file:

await seed.template.render({
  source: '<%= name %> v<%= 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

render() writes target directly and overwrites an existing file.

Render to String

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

const result = await seed.template.renderString(
  'Hello, <%= 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
<%= name %>Output value (not escaped; this package sets autoEscape: false)
<%~ html %>Output raw value
<% if (cond) { %> ... <% } %>JavaScript logic
<% for (const item of items) { %> ... <% } %>Loops
<%/* comment */%>Comments (not output)

Template variables are available both directly (name) and via it.name.

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

On this page