Skip to content

Core Helper Modules

core-helper-modules are the platform-agnostic, server-safe helper modules at the foundation of every project. They run unchanged in any JavaScript or Python runtime - browser, Node.js, React Native, Python interpreter - and are published under @your-org/*.

On This Page


Purpose

  • Provide generic, reusable, stateless functions that are universal and platform-agnostic
  • Run in any environment: browser, React Native, Node.js, Python
  • Never depend on server-only APIs (database drivers, AWS SDKs, filesystem writes)
  • Never depend on client-only APIs (DOM, window, navigator, mobile-specific APIs)

This is the layer that everything else stands on. If a function would behave differently in Node.js vs the browser, it does not belong here.


Design Principles

PrincipleWhy
Single responsibility per moduleModules stay small and focused
No business or domain logicReusable across projects
No application logicBelongs in the service layer, not in helpers
Pure functions preferredPredictable, testable, parallel-safe
Explicit inputs and outputsNo magic, no hidden context
No hidden stateFunctions return everything they produce
Explicit dependencies onlyInjected via the loader, never reached for
Language-specific implementationsOne module per [js|py] runtime

Naming Convention

Module directory name: [js|py]-helper-[module-name]

The core-helper-modules location at src/helper-modules-core/ makes the platform-agnostic intent visible at the path level.


Typical Files

FilePurpose
[module-name].jsPublic export surface for the module - exposes only the intended public functions
[module-name].config.js(Optional) module-specific constants and rules - defaults only, no process.env
provider/(Optional) vendor-specific implementations when the helper has multiple backends

Provider Folder (Multi-Vendor)

If a helper needs multiple implementations (for example, AWS vs GCP, or Chrome vs Firefox), place them under a provider/ folder. Provider selection happens via injected config; the helper delegates to the selected implementation.

Adding a new provider (e.g., gcp) should require only:

  • adding provider/gcp.js
  • registering it in the helper loader

No changes to application code.

Configuration

Helpers may support configuration optionally, only via explicit parameters at construction time (loader arguments). Helpers must never read environment variables, config files, or secret stores directly. If configuration is required, the parent loader provides it.


Example Modules

ModuleExample Functions
[js|py]-helper-utilsisNull, isBoolean, inArray, validateString, getUnixTime, safeParseJson
[js|py]-helper-debuginfo, error, performanceAuditLog
[js|py]-helper-timeDate/time math, timezone conversion, formatting
[js|py]-helper-moneysumMoney, formatMoney, roundMoney, compareMoney

Boundary Rules

Platform Neutrality (Hard Rule)

Core helper modules must be platform-agnostic. They must NOT:

  • Reference any platform identifier (web, rw, rn, ios, and)
  • Import browser APIs (DOM, window, document)
  • Import mobile-specific APIs (Android, iOS, React Native)
  • Depend on client runtime assumptions (screen, touch, lifecycle, navigation)

If a helper behaves differently across platforms, it does not belong in core-helper-modules.

Runtime Environment Constraints

Core helpers may assume server or neutral runtime only.

AllowedDisallowed
Node.js runtime (for js helpers)UI state
Python runtime (for py helpers)Event listeners
Standard language librariesClient lifecycle hooks
Pure computationRendering logic
Network or filesystem access (only if generic and configurable)User interaction assumptions

No Client-State Awareness

All context must be passed explicitly as function arguments. Core helpers must NOT:

  • Access cookies, localStorage, sessionStorage
  • Assume an authenticated user context
  • Read client identity, device, or locale implicitly
  • Cache data tied to a user or session

Configuration Isolation

Core helpers receive all configuration via explicit parameters passed by the parent loader. The parent loader is responsible for reading environment variables, config files, and secret stores.

The parent loader (in the consuming module) is responsible for:

  • Loading configuration values
  • Initializing the helper with the relevant config slice
  • Holding the initialized state if the helper module is stateful

Configuration loading belongs to:

  • Server core modules
  • Client modules
  • Dedicated config loaders

Side-Effect Discipline

Core helpers must clearly declare side effects.

AllowedDisallowed
Logging (via Lib.Debug)Implicit global state mutation
Database / network operations (via injected helper wrappers)Silent retries
Deterministic file operationsHidden caching
Background execution

Data Shape Independence

Core helpers must operate on generic data structures. Avoid domain-specific schemas. Avoid UI-specific data shapes.

VerdictExample
✅ AllowedformatMoney(amount, currency)
❌ Not allowedformatOrderTotal(orderData)

Testing and Reuse

  • Each helper module has its own unit tests and integration tests
  • Each module can be extracted into a standalone open-source package
  • A helper module may depend on another helper module, but no circular dependencies
  • Foundation modules (js-helper-utils, js-helper-debug) must never depend on each other or on any other helper - see peer-dependencies.md

If something is not domain-specific, give it its own helper module instead of putting it in the application core.


Further Reading

Released under the MIT License.