Utilities
A reference for the built-in helper utilities Thunder ships under @/core/utils.
Thunder ships with a set of production-ready helpers under @/core/utils/. This page covers the standalone utilities. Some larger utilities have their own pages: createCRUD, Caching, Logger, and the Env class.
denoConfig
Provides access to your project's deno.json configuration at runtime - useful for reading project metadata, import maps, tasks, or custom config values.
denoConfig is an already-resolved object (loaded at module initialization), not a function. Do not call it.
import { denoConfig, readDenoConfig, denoConfigPath } from "@/core/utils/denoConfig.ts";
console.log(denoConfig.name); // your project name
console.log(denoConfig.tasks); // configured deno tasks
// Read a different config file explicitly:
const other = await readDenoConfig("./plugins/foo/deno.json");
// Pass `true` as the second arg to read statically (JSON.parse, no import cache):
const fresh = await readDenoConfig(denoConfigPath, true);Template Rendering
Render EJS or Handlebars templates to strings. Both functions take the template content as a string (not a file path) plus a data object. ejsRender is async; handlebarsRender is sync.
import { ejsRender, handlebarsRender } from "@/core/utils/textRender.ts";
const html = await ejsRender("<h1>Hello <%= name %></h1>", { name: "Alice" });
const greeting = handlebarsRender("Hello {{name}}", { name: "Bob" });
// To render a file, read it first:
const tpl = await Deno.readTextFile("templates/welcome.ejs");
const out = await ejsRender(tpl, { name: "Alice", appName: "Thunder App" });
return new Response(html, { headers: { "Content-Type": "text/html" } });Hashing
One-way hashing built on Web Crypto (async) and Node crypto (sync). These produce digests only.
There is no verify helper - compare digests yourself. These are also not suitable for password storage on their own (no salting); use a dedicated KDF for passwords.
import {
createHash, // async, hex output
createHashBase64, // async, base64url output
createHashSync, // sync, hex output
createHashBase64Sync, // sync, base64url output
SupportedHashAlg,
} from "@/core/utils/hash.ts";
const hex = await createHash(SupportedHashAlg.SHA_256, "data");
const b64 = await createHashBase64(SupportedHashAlg.SHA_256, "data");
const hexSync = createHashSync(SupportedHashAlg.SHA_256, "data");
// Manual verification:
const isMatch = (await createHash(SupportedHashAlg.SHA_256, input)) === stored;Logger
A structured logging utility with colour-coded output for each severity level. Use Logger instead of console.log to maintain consistent, readable log output across your application.
import { Logger } from "@/core/utils/logger.ts";
Logger.success("Server started");
Logger.info("Connecting to database...");
Logger.warn("Rate limit approaching");
Logger.error("Failed to connect", error);| Method | Use Case |
|---|---|
Logger.success(msg) | Successful operations (e.g. startup, insert) |
Logger.info(msg) | General informational messages |
Logger.warn(msg) | Non-critical warnings |
Logger.error(msg, err?) | Errors and exceptions |
Only errors are logged in production mode.
parseQueryParams
Parses a query string into a nested object via qs. It takes a string (not a Request).
import { parseQueryParams } from "@/core/utils/parseQueryParams.ts";
const params = parseQueryParams("?page=1&filter[status]=active");
// { page: "1", filter: { status: "active" } }Inside route handlers, prefer queryAsJson(req) from @/core/http/utils.ts - it wraps parseQueryParams for requests and pairs naturally with Zod via $query.parse(queryAsJson(req)). See Routes.
paginated
Repeatedly invokes a callback in fixed-size pages until a page returns fewer items than limit (i.e. the last page). Useful for batch-processing an entire collection without loading it all into memory at once.
import { paginated } from "@/core/utils/paginate.ts";
await paginated(100, async (offset, limit) => {
const batch = await collection.find().skip(offset).limit(limit).toArray();
for (const doc of batch) {
// process each doc...
}
return batch.length; // loop continues while this equals `limit`
});See Also
These utilities also live under @/core/utils/ but have dedicated pages:
- createCRUD and
$objectId(createCRUD.ts) - Caching -
cache(cache.ts) - Environment Variables - the
Envclass (env.ts)