Utility toolkit for JavaScript & TypeScript.
atron-js gives you a focused set of clear, well-tested helpers for working with strings, numbers, and time in projects of any size.
- Simple, readable code – written with clear, explicit logic.
- TypeScript first – full type definitions out of the box.
- Tiny surface area – a handful of core utilities instead of a huge API.
- Well-tested – uses Node's built-in test runner with lots of test cases.
npm install atron-jsatron-js supports both ES modules and CommonJS in Node and bundlers.
// ESM / TypeScript
import { tryCatch, getJSON } from "atron-js";
// CommonJS
const { tryCatch, getJSON } = require("atron-js");Fetch-based helpers (getJSON, postJSON, etc.) require environments with a
global fetch implementation (for example Node 18+ or modern browsers).
import {
capitalize,
reverse,
isEmpty,
randomNumber,
isEven,
clamp,
delay,
formatTime,
} from "atron-js";
console.log(capitalize("hello")); // "Hello"
console.log(reverse("abc")); // "cba"
console.log(isEmpty(" ")); // true
console.log(randomNumber(1, 6)); // e.g. 4
console.log(isEven(10)); // true
console.log(clamp(150, 0, 100)); // 100
await delay(1000);
console.log(formatTime(new Date())); // e.g. "14:05"atron-js is designed as a small, focused utility library:
- The implementations are short and readable – you can open the source and understand them quickly.
- The functions do one clear thing with sensible, predictable behavior.
- The test suite covers many real-world cases to keep behavior reliable.
Use it for:
- Web and backend applications.
- Scripts, tools, and CLIs.
- Libraries, SDKs, or other shared codebases.
All functions are exported from the root module:
import { ... } from "atron-js";Wraps a value-returning or promise-returning function and returns a tuple
[data, error] instead of throwing.
import { tryCatch, getJSON } from "atron-js";
const [user, err] = await tryCatch(() => getJSON<User>("/api/user/1"));
if (err) {
// handle error
} else {
console.log(user.id);
}Fetch JSON from a URL with status checking, content-type validation, and optional timeout.
import { getJSON } from "atron-js";
const user = await getJSON<User>("https://api.example.com/user/1", {
timeoutMs: 5000,
});Send a JSON POST request and parse the JSON response.
import { postJSON } from "atron-js";
const created = await postJSON("https://api.example.com/users", {
name: "Atron",
});Retry an async function a fixed number of times before failing.
import { retry, getJSON } from "atron-js";
const data = await retry(
() => getJSON("https://api.example.com/flaky"),
3,
250
);Wrap a promise and reject with a timeout error if it takes too long.
import { timeout, getJSON } from "atron-js";
const data = await timeout(getJSON("/slow-endpoint"), 2000);Sleep for a given number of milliseconds.
import { sleep } from "atron-js";
await sleep(500);Run async tasks one-by-one and collect their results.
import { sequence, getJSON } from "atron-js";
const urls = ["/step1", "/step2", "/step3"];
const tasks = urls.map(url => () => getJSON(url));
const results = await sequence(tasks);Run async tasks in parallel with an optional concurrency limit.
import { parallel, getJSON } from "atron-js";
const urls = ["/a", "/b", "/c", "/d"];
const tasks = urls.map(url => () => getJSON(url));
const results = await parallel(tasks, 2); // at most 2 at a timeSplit an array into evenly sized batches.
import { batch } from "atron-js";
const groups = batch([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]Log a green checkmark with the message. Useful for positive status updates.
import { success } from "atron-js";
success("Deployment finished");
// ✔ Deployment finishedLog a bold red error with a leading "✖". Does not throw; only logs.
import { error } from "atron-js";
error("Failed to connect to database");
// ✖ Failed to connect to databaseLog a yellow warning with a "⚠ Warning:" prefix.
import { warning } from "atron-js";
warning("Using default configuration");
// ⚠ Warning: Using default configurationLog an informational message with a blue "ℹ Info:" prefix.
import { info } from "atron-js";
info("Server listening on port 3000");
// ℹ Info: Server listening on port 3000Log a dim gray debug message with a "🐞 Debug:" prefix. Only logs when
NODE_ENV is not "production".
import { debug } from "atron-js";
debug("Got payload: " + JSON.stringify(payload));
// 🐞 Debug: Got payload ... (only when NODE_ENV !== "production")Print a bold, underlined cyan title to separate sections.
import { title } from "atron-js";
title("Build Summary");Wrap a message (optionally multi-line) in an ASCII box, colored magenta.
import { box } from "atron-js";
box("Deployment complete\nAll services healthy");Print a simple uppercase banner framed by = characters in bright green.
import { banner } from "atron-js";
banner("ATRON JS");Log a message prefixed with a [HH:MM:SS] timestamp.
import { timestamp } from "atron-js";
timestamp("Job finished");
// [12:34:56] Job finishedPretty-print JSON with basic coloring:
- Keys yellow
- Strings green
- Numbers/booleans cyan
import { logJSON } from "atron-js";
logJSON({ id: 1, name: "Atron", active: true });Capitalizes the first character of the string. If the string is empty, returns "".
capitalize("hello"); // "Hello"
capitalize("hELLO"); // "HELLO"
capitalize(""); // ""
capitalize(" space"); // " space" (leading space is unchanged)How it works:
- If
textis falsy (empty string), it returns"". - Otherwise, it uppercases
text.charAt(0)and appends the rest of the string.
Returns a new string with characters in reverse order.
reverse("abc"); // "cba"
reverse("racecar"); // "racecar"
reverse("hello world"); // "dlrow olleh"How it works:
- Splits the string into an array of characters, reverses the array, and joins it back.
Checks if a string is empty or contains only whitespace.
isEmpty(""); // true
isEmpty(" "); // true
isEmpty("\n\t"); // true
isEmpty("hello"); // false
isEmpty(" hello "); // falseHow it works:
- If
textis falsy ortext.trim().length === 0, it returnstrue.
Returns a random integer between min and max (inclusive).
randomNumber(1, 6); // 1–6, like a dice roll
randomNumber(0, 0); // always 0
randomNumber(-5, 5); // -5..5How it works:
- Uses
Math.random()andMath.floor()to map the random value into the[min, max]range.
Note: This is a simple helper, not cryptographically secure.
Returns true if the number is even, false otherwise.
isEven(2); // true
isEven(3); // false
isEven(0); // true
isEven(-4); // trueHow it works:
- Uses the remainder operator:
num % 2 === 0.
Restricts a number to stay within the [min, max] range.
clamp(5, 0, 10); // 5 (already in range)
clamp(-5, 0, 10); // 0 (clamped up)
clamp(15, 0, 10); // 10 (clamped down)How it works:
- First takes
Math.max(num, min), thenMath.min(result, max).
"Sleep" for the given number of milliseconds. This is useful in async code, demos, or simple retry loops.
console.log("Start");
await delay(1000);
console.log("One second later");How it works:
- Wraps
setTimeoutin aPromisethat resolves aftermsmilliseconds.
Formats a Date into a simple 24-hour "HH:MM" string using your local time zone.
const date = new Date(2020, 0, 1, 14, 5); // 14:05 local time
formatTime(date); // "14:05"How it works:
- Uses
date.toTimeString()and slices the first 5 characters (HH:MM).
src/
index.ts # Re-exports all utilities
utils/
strings.ts # String helpers
numbers.ts # Number helpers
time.ts # Time helpers
tests/ # Node built-in tests (node:test)
dist/ # Compiled output (generated by tsc)
This project uses Node's built-in test runner (node:test) with tsx for TypeScript.
npm testRequirements:
- Node.js 18+ (Node 20+ recommended) for the Node test runner.
Contributions are welcome! Please read the contribution guide for details on setup, testing, and proposing changes.
If you want to discuss ideas or coordinate work in real time, you can join the Discord server: https://discord.gg/eAgnBPUf
MIT – see the license in package.json.