NestJS Packages

Template reference

Color tokens, utility classes, and EJS helpers available when building a custom collector panel template.

All profiler templates share a single design system based on Tailwind CSS 4 (loaded via CDN) and a set of semantic CSS custom properties defined in _head.ejs. Any .ejs template registered through a custom collector automatically has access to every class and helper described here.

Building your first custom collector? Follow the Build a custom collector tutorial first, then come back here as a reference while writing your EJS template.

Color tokens

Tokens adapt automatically to the light/dark theme. Use the Tailwind utility name (e.g. text-foreground) in your template — never hardcode hex values.

Neutral / surface

Tailwind classPurpose
bg-backgroundPage background
bg-surfaceCard / panel background
bg-surface-mutedDimmed surface (table header, code block background)
bg-surface-activeActive / selected surface

Text

Tailwind classPurpose
text-foregroundPrimary content text
text-foreground-secondarySecondary content (metadata, values)
text-foreground-mutedLabels, column headers
text-foreground-faintTimestamps, disabled states, placeholders

Borders

Tailwind classPurpose
border-lineDefault border (cards, tables)
border-line-subtleRow divider inside a table
border-line-activeFocused / highlighted border

Status

Tailwind classPurpose
text-danger / bg-danger-bg / border-danger-lineError state — text, background, border
border-danger-line-subtleSubtle danger border (stack trace separator)
text-successSuccess state
text-code-textMonospace code content

Brand

Tailwind classPurpose
text-nest / bg-nest / border-nestNestJS brand red — active tab indicator, accent
text-nest-lightLighter brand red for hover
text-nest-darkDarker brand red for pressed states

Typography

ClassValuePurpose
text-2xs0.625rem (10px)Smallest label size — column headers, badges
text-xs0.75rem (12px)Primary content in tables and panels
font-monoMonospace font for code, identifiers, URLs

Badge utility classes

Ready-to-use semantic badges. Apply them on a <span> together with px-1.5 py-0.5 rounded text-2xs font-bold tracking-wide.

HTTP method

ClassColourUse for
badge-getGreenGET / read operations
badge-postBluePOST / insert operations
badge-putAmberPUT / update operations
badge-patchOrangePATCH / partial update
badge-deleteRedDELETE / remove operations
badge-headPurpleHEAD operations
badge-optionsSlateOPTIONS operations
badge-defaultSlateUnknown / fallback

HTTP status

ClassUse for
badge-2xx2xx success responses
badge-3xx3xx redirects
badge-4xx4xx client errors
badge-5xx5xx server errors

Log level

ClassUse for
badge-logLOG
badge-warnWARN
badge-errorERROR
badge-debugDEBUG
badge-verboseVERBOSE
badge-fatalFATAL

Duration classes

Colour-code a duration value based on thresholds.

ClassConditionColour
dur-fast< 100 msGreen
dur-medium100 – 500 msAmber
dur-slow> 500 msRed
dur-noneUnknown / undefinedFaint grey
<%
  const cls = dur < 100 ? 'dur-fast' : dur < 500 ? 'dur-medium' : 'dur-slow';
%>
<span class="<%= cls %> text-xl font-bold tabular-nums"><%= dur %>ms</span>

EJS helper functions

These functions are automatically injected into every template.

HelperSignatureDescription
toJson(value) → stringPretty-prints any value as indented JSON
isoDate(timestamp: number) → stringFormats a Unix ms timestamp as YYYY-MM-DD HH:MM:SS
timeOnly(timestamp: number) → stringFormats a Unix ms timestamp as HH:MM:SS.mmm
highlightSql(sql: string) → HTML stringWraps SQL keywords in <span class="sql-keyword"> — use with <%-
methodClass(method: string) → stringReturns the correct badge-* class for an HTTP method
statusClass(status: number) → stringReturns the correct badge-* class for an HTTP status code
logLevelClass(level: string) → stringReturns the correct badge-* class for a log level
mb(bytes: number) → stringConverts bytes to a human-readable X.XX MB string
kvTable(data: Record<string, unknown>) → HTML stringRenders a key/value table — use with <%-

Common template patterns

Empty state

<div class="py-8 text-center bg-surface-muted border border-line rounded-lg">
  <p class="text-foreground-muted text-sm">No entries for this request.</p>
</div>

Summary bar

<div class="flex items-center gap-4 text-xs text-foreground-muted mb-4">
  <span><strong class="text-foreground"><%= items.length %></strong> entries</span>
  <span><strong class="text-foreground"><%= totalDuration %></strong>ms total</span>
</div>

Data table

<div class="rounded-lg border border-line overflow-hidden">
  <table class="w-full">
    <thead>
      <tr class="bg-surface-muted border-b border-line">
        <th class="text-left py-2.5 px-4 text-foreground-muted font-medium text-2xs uppercase tracking-widest">Name</th>
        <th class="text-right py-2.5 px-4 text-foreground-muted font-medium text-2xs uppercase tracking-widest w-24">Duration</th>
        <th class="text-left py-2.5 px-4 text-foreground-muted font-medium text-2xs uppercase tracking-widest w-20">Time</th>
      </tr>
    </thead>
    <tbody class="divide-y divide-line-subtle">
      <% for (const item of items) { %>
        <tr class="hover:bg-surface-muted transition-colors">
          <td class="py-2 px-4 text-foreground text-xs"><%= item.name %></td>
          <td class="py-2 px-4 text-right text-foreground-secondary text-xs tabular-nums"><%= item.duration %>ms</td>
          <td class="py-2 px-4 text-foreground-faint text-2xs tabular-nums"><%= timeOnly(item.startedAt) %></td>
        </tr>
      <% } %>
    </tbody>
  </table>
</div>

Badge

<span class="px-1.5 py-0.5 rounded text-2xs font-bold tracking-wide badge-get">GET</span>

Code block (JSON)

<pre class="bg-surface-muted border border-line rounded-lg p-4 text-xs overflow-x-auto leading-relaxed">
  <code class="language-json"><%= toJson(value) %></code>
</pre>

Highlight.js runs automatically on DOMContentLoaded — any <code class="language-*"> block is highlighted.

SQL with keyword highlighting

<code class="text-xs text-code-text leading-relaxed break-all">
  <%- highlightSql(query.sql) %>
</code>
<style>.sql-keyword { color: #818cf8; font-weight: 600; }</style>

Error inline

<% if (item.error) { %>
  <div class="mt-1 text-danger text-2xs">Error: <%= item.error %></div>
<% } %>

Section with heading

<section class="mb-6">
  <h2 class="text-foreground-muted text-2xs uppercase tracking-widest font-semibold mb-3">
    My Section
  </h2>
  <!-- content -->
</section>

Dark mode

All semantic token classes (text-foreground, bg-surface, border-line, badge classes, duration classes) adapt automatically — no extra dark: variants needed. When you need Tailwind colour palette classes (e.g. bg-blue-100) always add the corresponding dark: variant:

<span class="bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300">
  INFO
</span>

On this page