Skip to content

postRenderHooks

In Kanel, "rendering" means translating a bunch of declarations into arrays of strings that will ultimately become files. You can apply hooks before and after this step if you want to make some custom modifications or additions to the final output.

Post-render hooks run after files have been rendered to strings, just before they're written to disk. This is useful for making low-level string manipulations that would be difficult to express at the declaration level.

Signature

A post-render hook has the following signature:

typescript
export type PostRenderHook = (
  path: string,
  lines: string[],
) => Awaitable<string[]>;

For every file that is about to be written, this function will be called. The lines parameter is the raw strings that will comprise the file. You should return the entire array of lines that you want the file to contain.

Built-in Hooks

Mark Files as Generated

The markAsGenerated hook adds a @generated comment to the top of each file:

typescript
import { makePgTsGenerator, markAsGenerated } from 'kanel';

const config = {
  generators: [makePgTsGenerator()],
  postRenderHooks: [markAsGenerated],
};

This adds:

typescript
// @generated
// This file is automatically generated by Kanel. Do not modify manually.

Format with Prettier

The formatWithPrettier hook automatically formats all TypeScript files using Prettier:

typescript
import { makePgTsGenerator, formatWithPrettier } from 'kanel';

const config = {
  generators: [makePgTsGenerator()],
  postRenderHooks: [formatWithPrettier],
};

This hook:

  • Only formats TypeScript files (.ts and .tsx)
  • Automatically finds and respects your Prettier configuration (.prettierrc, etc.)
  • Gracefully handles cases where Prettier is not installed
  • Requires Prettier as an optional peer dependency

TIP

You can combine multiple hooks:

typescript
postRenderHooks: [markAsGenerated, formatWithPrettier]

WARNING

Make sure Prettier is installed in your project:

bash
npm install --save-dev prettier

Accessing Context

To access the Kanel context (configuration, schemas, etc.) in a post-render hook, use useKanelContext():

typescript
import { useKanelContext } from 'kanel';

const myPostRenderHook = (path, lines) => {
  const context = useKanelContext();
  // Access context.config, context.schemas, context.typescriptConfig

  return lines;
};

See useKanelContext for complete documentation.

Example: Custom Header

typescript
const addCustomHeader = (path, lines) => {
  return [
    '// Custom header',
    `// Generated from: ${path}`,
    '// Do not edit manually',
    '',
    ...lines,
  ];
};

const config = {
  generators: [makePgTsGenerator()],
  postRenderHooks: [addCustomHeader],
};

Example: Add Prettier Disable Comments

typescript
const disablePrettier = (path, lines) => {
  return [
    '/* prettier-ignore-start */',
    ...lines,
    '/* prettier-ignore-end */',
  ];
};

V3 to V4 Migration

In V3, post-render hooks received InstantiatedConfig as the third parameter. In V4, hooks no longer receive config as a parameter — use useKanelContext() instead if you need access to configuration.

V3 pattern (deprecated):

typescript
module.exports = {
  postRenderHooks: [
    (path, lines, instantiatedConfig) => {
      // Access instantiatedConfig.outputPath, etc.
      return lines;
    },
  ],
};

V4 pattern:

typescript
import { useKanelContext } from 'kanel';

module.exports = {
  generators: [makePgTsGenerator()],
  postRenderHooks: [
    (path, lines) => {
      const context = useKanelContext();
      // Access context.config.outputPath, etc.
      return lines;
    },
  ],
};

When to Use Post-Render Hooks vs Pre-Render Hooks

Use pre-render hooks when you want to:

  • Add/modify/remove TypeScript declarations
  • Generate additional types or interfaces
  • Work with the semantic structure of the code

Use post-render hooks when you want to:

  • Add file headers or footers
  • Make string-based transformations
  • Add linter/formatter directives
  • Perform simple line-based modifications

Pre-render hooks are generally more powerful and type-safe, but post-render hooks are simpler for basic string operations.