# How to Use Node.js ESM with Garden Skills Without npm install

> Learn to run Node.js ESM with Garden Skills without npm install. Clone the repo and import skills directly using native ESM syntax for a streamlined workflow.

- Repository: [ConardLi/garden-skills](https://github.com/ConardLi/garden-skills)
- Tags: how-to-guide
- Published: 2026-09-01

---

**You can run Garden Skills as native ES Modules directly with Node.js 20+ by cloning the repository and importing skill files using standard ESM syntax, eliminating the need for an npm install step because the codebase relies exclusively on built-in Node.js modules.**

Garden Skills by ConardLi is a pure-Node.js repository that ships with native ES Module support configured out of the box. Because every skill relies only on Node.js built-in APIs like `node:process` and `node:path`, you can import and execute functionality immediately after cloning—no package installation required.

## Why Garden Skills Works Without npm install

The repository root contains a [`package.json`](https://github.com/ConardLi/garden-skills/blob/main/package.json) that declares `"type": "module"`【/cache/repos/github.com/ConardLi/garden-skills/main/package.json#L6-L7】. This setting instructs Node.js to treat all `.js` files as ES Modules, enabling native `import` syntax throughout the codebase.

Additionally, the `engines` field specifies **Node.js ≥ 20**【/cache/repos/github.com/ConardLi/garden-skills/main/package.json#L13-L15】, ensuring you have the modern ESM features and stable fetch APIs that the skills rely on. Since no external dependencies are declared in [`package.json`](https://github.com/ConardLi/garden-skills/blob/main/package.json), the entire codebase operates using only Node.js standard library modules.

## Importing Skills as ES Modules

You can import Garden Skills into your own scripts using standard static imports or dynamic imports. The skill files expose their functionality through clean ESM exports located in the `skills/<name>/scripts/` directories.

### Static Import Approach

Create a wrapper script in the repository root:

```js
// wrapper.mjs
import { run as generateImage } from './skills/gpt-image-2/scripts/generate.js';

await generateImage();

```

Run it with:

```bash
node wrapper.mjs --prompt "A sunrise garden" --image out/garden.png

```

The [`generate.js`](https://github.com/ConardLi/garden-skills/blob/main/generate.js) file imports only built-in modules and internal helpers like [`./shared.js`](https://github.com/ConardLi/garden-skills/blob/main/./shared.js)【/cache/repos/github.com/ConardLi/garden-skills/main/skills/gpt-image-2/scripts/generate.js#L1-L18】, ensuring zero external dependencies resolve.

### Dynamic Import Approach

For on-the-fly execution, use `import()` with a `file://` URL:

```js
const { run: generateImage } = await import(
  new URL('./skills/gpt-image-2/scripts/generate.js', import.meta.url)
);
await generateImage();

```

This pattern is useful when building CLI tools that conditionally load specific Garden Skills based on user input.

## Running Skills from the Command Line

You can execute any skill directly without creating a wrapper file. Since the entry point scripts handle their own CLI argument parsing using `node:process`, standalone execution works immediately:

```bash
node ./skills/gpt-image-2/scripts/generate.js \
  --prompt "A futuristic garden at night" \
  --image out/night.png

```

Because [`./skills/gpt-image-2/scripts/generate.js`](https://github.com/ConardLi/garden-skills/blob/main/./skills/gpt-image-2/scripts/generate.js) imports only Node.js built-ins and relative internal modules, the command succeeds without an `npm install` step.

## Using Skills Programmatically in Your Projects

Beyond running CLI commands, you can import individual utility functions from skill modules to build custom workflows. The [`shared.js`](https://github.com/ConardLi/garden-skills/blob/main/shared.js) files expose helper functions that handle API communication and payload construction.

```js
// my-app.mjs
import { readPromptInput, buildPayload, postJson } from 
  './skills/gpt-image-2/scripts/shared.js';

async function createImage(prompt) {
  const cfg = { model: 'dall-e-3', size: '1024x1024' };
  const payload = buildPayload(cfg, prompt);
  const url = `${process.env.OPENAI_BASE_URL}/images/generations`;

  const response = await postJson(url, payload);
  console.log('OpenAI response:', response);
}

await createImage('A robot tending flowers');

```

This approach treats Garden Skills as a library rather than a CLI tool, giving you fine-grained control over the execution flow while maintaining the zero-dependency architecture.

## Summary

- **Garden Skills** uses `"type": "module"` in [`package.json`](https://github.com/ConardLi/garden-skills/blob/main/package.json)【/cache/repos/github.com/ConardLi/garden-skills/main/package.json#L6-L7】 to enable native ESM throughout the repository.
- **Node.js 20+** is required【/cache/repos/github.com/ConardLi/garden-skills/main/package.json#L13-L15】, providing the modern module system and APIs the skills depend on.
- **No npm install** is needed because skills import only Node.js built-ins (`node:process`, `node:path`) and internal relative paths like [`./shared.js`](https://github.com/ConardLi/garden-skills/blob/main/./shared.js).
- You can import skills using **static imports** for direct use or **dynamic imports** for conditional loading.
- Skills can run **standalone from the command line** or be **imported as libraries** into your own ESM projects.

## Frequently Asked Questions

### Does Garden Skills require any external npm packages?

No. According to the ConardLi/garden-skills source code, the repository contains no dependencies in [`package.json`](https://github.com/ConardLi/garden-skills/blob/main/package.json) and imports only Node.js built-in modules such as `node:process` and `node:path`. Each skill relies on relative imports from internal files like [`./shared.js`](https://github.com/ConardLi/garden-skills/blob/main/./shared.js) rather than external packages.

### Can I use Garden Skills with CommonJS require()?

No. The repository explicitly sets `"type": "module"` in the root [`package.json`](https://github.com/ConardLi/garden-skills/blob/main/package.json), which forces Node.js to treat all `.js` files as ES Modules. You must use the ESM `import` syntax or dynamic `import()` function. If you need CommonJS compatibility, you would need to rename files to `.cjs` or change the package type, which is not recommended for this codebase.

### What Node.js version do I need to run Garden Skills?

Node.js 20 or higher is required. The `engines` field in [`package.json`](https://github.com/ConardLi/garden-skills/blob/main/package.json) specifies `node >= 20`【/cache/repos/github.com/ConardLi/garden-skills/main/package.json#L13-L15】, ensuring support for modern ESM features, stable fetch implementations, and other APIs used by the skills.

### How do I pass arguments when importing a skill programmatically?

When importing the `run` function from a skill file like [`skills/gpt-image-2/scripts/generate.js`](https://github.com/ConardLi/garden-skills/blob/main/skills/gpt-image-2/scripts/generate.js), the function reads from `process.argv` internally. You can invoke it directly after setting environment variables, or import lower-level functions from [`./shared.js`](https://github.com/ConardLi/garden-skills/blob/main/./shared.js) (such as `readPromptInput`, `buildPayload`, and `postJson`) to bypass CLI parsing and pass arguments as function parameters instead.