Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/g-js-api/G.js/llms.txt

Use this file to discover all available pages before exploring further.

By default, importing @g-js-api/g.js injects roughly 50 names — group, trigger_function, counter, on, touch, and many more — directly into the global scope of your JavaScript environment. This is convenient for quick scripts and one-file levels, but it can cause conflicts in larger projects, confuse TypeScript’s type checker, or break tools that lint for undeclared globals. G.js ships an alternative entry point, @g-js-api/g.js/safe, that gives you the exact same API as named exports so you import only what you need.

The Problem with the Default Import

When you write:
import '@g-js-api/g.js';
G.js registers all of its functions on the globalThis object. This means that anywhere in your program, names like unknown_g, particle_system, sepia, and keyframe_system are available without any import statement — but also without any explicit declaration. In a multi-file project or a TypeScript codebase this creates ambiguity about where values come from and makes tree-shaking impossible.

The Solution: Safe Mode

import { $, group, counter, on, touch, exportConfig } from '@g-js-api/g.js/safe';
The /safe entry point exports everything as named exports. Nothing is written to globalThis. Your bundler, linter, and TypeScript compiler can all see exactly which parts of G.js your file depends on.

What Safe Mode Exports

Every function and constant available in the global mode is also exported by /safe. This includes:
ExportDescription
$The main G.js object ($.exportConfig, $.add, etc.)
exportConfigConfigure and trigger level export
groupReference a specific group by ID
colorReference a specific color channel by ID
objectCreate a GD object
trigger_functionCreate a trigger function group
unknown_gAllocate the next free group ID
unknown_cAllocate the next free color ID
unknown_bAllocate the next free block ID
levelThe current level helper (level.objects, level.get_objects)
obj_propsObject property name dictionary
levelstringParse a level string into objects
levelstring_to_objLow-level level string → Dictionary[] converter
extractSPWN-style extract — puts dict values into scope
waitInsert a spawn delay
rangeCreate a numeric range
speedLevel speed constant
exportConfig is available both as a named export and as $.exportConfig. In safe mode you can use either form — the standalone named export is convenient when you only need it once at the top of your script.

TypeScript Support

In global mode, G.js ships a src/runtime.d.ts ambient declaration file that tells TypeScript about all the names injected into global scope. When you use safe mode, that file is irrelevant — every type comes directly from the /safe module imports, which are fully typed. This means safe mode is the recommended choice for TypeScript projects: your IDE will provide accurate autocomplete and type checking without needing the ambient declaration file installed.
// TypeScript safe-mode example — all types inferred from imports
import {
  $,
  unknown_g,
  trigger_function,
  on,
  touch,
  counter,
  exportConfig
} from '@g-js-api/g.js/safe';

await exportConfig({ type: 'savefile', options: { info: true } });

const my_group = unknown_g();   // inferred as $group
const my_counter = counter(0);  // inferred as Counter

Complete Safe Mode Script

The following script shows a fully self-contained safe-mode level that moves a group and increments a counter on touch:
import {
  $,
  group,
  unknown_g,
  trigger_function,
  counter,
  on,
  touch,
  wait,
  obj_props,
  object,
  exportConfig
} from '@g-js-api/g.js/safe';

await exportConfig({ type: 'savefile', options: { info: true } });

// Allocate IDs
const my_group = unknown_g();
const my_counter = counter(0);

// Place an object and assign it to our group
object({
  [obj_props.OBJ_ID]: 1,
  [obj_props.X]: 45,
  [obj_props.Y]: 45,
  [obj_props.GROUPS]: my_group
}).add();

// On touch: move the object and increment the counter
on(touch(), trigger_function(() => {
  my_group.move(30, 0, 0.5);
  wait(0.5);
  my_group.move(-30, 0, 0.5);
  my_counter.add(1);
}));

Using extract() with Safe Mode

extract(dict) is a SPWN-inspired helper that takes a dictionary and injects its values into global scope. This is useful with constant objects — for example, you can extract the easing constants so you can write BOUNCE_OUT instead of constants.BOUNCE_OUT:
import {
  extract,
  BOUNCE_OUT,
  EASE_IN_OUT,
  ELASTIC_OUT,
  keyframe_system,
  exportConfig
} from '@g-js-api/g.js/safe';

await exportConfig({ type: 'savefile', options: { info: true } });

// Extract easing constants into global scope for shorter syntax
extract({ BOUNCE_OUT, EASE_IN_OUT, ELASTIC_OUT });

// Now usable without the import prefix in subsequent inline calls
const anim = keyframe_system();
anim.keyframe(0, 60, 0, 1, 0.8, 0.4, ELASTIC_OUT).add();
extract() does write to globalThis, which partially negates the namespace benefits of safe mode. Use it sparingly and only with well-understood constant dictionaries.

When to Use Safe Mode vs Global Mode

Use Safe Mode When…

  • Building a TypeScript project where you want accurate type inference
  • Working with multiple modules that each import G.js separately
  • Following strict ESLint rules that disallow implicit globals
  • You want explicit control over which G.js features are used in each file

Use Global Mode When…

  • Writing a quick one-file script for a small level
  • You’re a beginner and don’t want to think about import statements
  • The level logic is entirely in a single file with no module boundaries
  • You’re porting a SPWN script and want the most familiar syntax

Installation

Set up G.js in your project with npm.

Quick Start

Build your first level with the global API.

Level Reader

Read and modify existing GD levels from scripts.

Export Modes

Configure savefile, levelstring, live_editor, and gmd exports.

Build docs developers (and LLMs) love