# fount

> A source from which dependencies flow

Latest version **1.2.0** (published 2026-01-31) · MIT license · 0 weekly downloads

## Install

```sh
npm install fount
pnpm add fount
yarn add fount
bun add fount
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.2.0 |
| Published | 2026-01-31 |
| First published | 2014-07-15 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=22 |
| Dependencies | 3 |
| Unpacked size | 64.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Alex Robson |
| Maintainers | arobson |
| Keywords | DI, IoC, dependency, injection |

## Links

- npm: https://www.npmjs.com/package/fount
- Repository: https://github.com/arobson/fount
- Issues: https://github.com/arobson/fount/issues
- npm.io page: https://npm.io/package/fount

## Dependencies (3)

- [debug](https://npm.io/package/debug.md) ^4.3.1
- [fauxdash](https://npm.io/package/fauxdash.md) ^1.8.6
- [eslint-import-resolver-node](https://npm.io/package/eslint-import-resolver-node.md) ^0.3.9

## Alternatives

- [memory-cache](https://npm.io/package/memory-cache.md) — 795.0K weekly downloads
- [@httptoolkit/proxy-agent](https://npm.io/package/@httptoolkit/proxy-agent.md) — 11.2K weekly downloads
- [express-cache-controller](https://npm.io/package/express-cache-controller.md) — 5.3K weekly downloads
- [http-cache-middleware](https://npm.io/package/http-cache-middleware.md) — 4.5K weekly downloads
- [cache2](https://npm.io/package/cache2.md) — 1.5K weekly downloads

## Recent versions

- 1.2.0 (latest) — 2026-01-31
- 1.1.5 — 2021-01-30
- 1.1.4 — 2018-03-02
- 1.1.3 — 2017-07-16
- 1.1.2 — 2017-07-16
- 1.1.1 — 2017-07-14
- 1.1.0 — 2017-07-14
- 1.0.1 — 2017-07-13
- 1.0.0 — 2017-07-08
- 1.0.0-4 — 2017-03-11
- 1.0.0-3 — 2017-03-01
- 1.0.0-2 — 2017-03-01
- 1.0.0-1 — 2017-02-25
- 0.1.1-1 — 2017-02-25
- 0.2.0-3 — 2016-04-23
- … 9 more at https://npm.io/package/fount/versions

## README

# Fount

Fount provides synchronous and asynchronous dependency injection with automatic deferred resolution.

## Getting Started

```bash
npm i fount
```

```typescript
import { fount } from 'fount';
```

## Key Features

- **Deferred Resolution**: When resolving dependencies that haven't been registered yet, fount will wait until they become available rather than throwing an error.
- **Multiple Containers**: Organize dependencies into namespaced containers.
- **Scoped Resolution**: Cache factory results per scope for memoization.
- **Flexible Registration**: Register values, factories, or npm modules.

## Dependency Identification Styles

Fount supports two styles of identifying dependencies:

```typescript
// By argument name - each argument is looked up by name in fount's store
fount().inject((one, two, three) => {
  // your code here
});

// By string array - dependencies are looked up and passed in order
fount().inject(['one', 'two', 'three'], (one, two, three) => {
  // your code here
});
```

The string array approach is recommended for production code as minifiers will rename function arguments and break name-based resolution.

## Multiple Containers

Fount supports multiple dependency containers identified by namespace. If you don't specify one, it uses the `default` namespace.

You can use a non-default namespace in two ways:
- Pass the namespace in parenthesis before making the call
- Use period-delimited namespaces in your key names

```typescript
// Using the default namespace
const value = await fount().resolve('myKey');

// Using a named namespace
const value = await fount('myContainer').resolve('myKey');

// Using period-delimited keys to access other namespaces
const value = await fount().resolve('myContainer.myKey');
```

## Scopes

Scopes work with factory dependencies to provide memoization. The first time a scoped factory is resolved within a scope, the result is cached. Subsequent resolutions within the same scope return the cached value.

```typescript
// Register a scoped factory
fount().registerFactory('timestamp', () => Date.now(), 'scoped');

// First call computes the value
const t1 = await fount().resolve('timestamp', 'myScope');

// Second call returns cached value
const t2 = await fount().resolve('timestamp', 'myScope');

console.log(t1 === t2); // true
```

### Purging Scopes

```typescript
// Purge a specific scope from the default namespace
fount().purgeScope('myScope');

// Purge all scopes from the default namespace
fount().purgeScopes();

// Purge a specific scope from a named namespace
fount('example').purgeScope('myScope');

// Purge all scopes from a named namespace
fount('example').purgeScopes();
```

## Registering Dependencies

### Values

Register static values that fount returns as-is:

```typescript
fount().register('port', 8080);
fount().register('config', { debug: true, maxRetries: 3 });
fount('custom').register('apiKey', 'secret-key');
```

### Factories

Register functions that fount invokes during resolution:

```typescript
// Simple factory
fount().registerFactory('timestamp', () => Date.now());

// Factory with dependencies
fount().registerFactory('connection', ['host', 'port'], (host, port) => {
  return createConnection(host, port);
});

// Dependencies inferred from argument names
fount().registerFactory('connection', (host, port) => {
  return createConnection(host, port);
});
```

### Factory Lifecycles

Factories support three lifecycles:

- **factory** (default): Invoked on every resolution
- **static**: Invoked once, result is cached permanently
- **scoped**: Invoked once per scope, result is cached per scope

```typescript
// Factory lifecycle - new instance every time
fount().registerFactory('id', () => generateId(), 'factory');

// Static lifecycle - computed once, cached forever
fount().registerFactory('startTime', () => Date.now(), 'static');

// Scoped lifecycle - computed once per scope
fount().registerFactory('requestId', () => generateId(), 'scoped');
```

### NPM Modules

Register npm modules directly:

```typescript
fount().registerModule('lodash');

// Later, resolve it
const _ = await fount().resolve('lodash');
```

If the module exports a function that fount cannot resolve dependencies for, it provides the function as-is.

## Asynchronous Methods

These methods return promises and support deferred resolution - if a dependency isn't registered yet, fount waits until it becomes available.

### resolve

Resolve a single dependency:

```typescript
const port = await fount().resolve('port');

// With scope
const value = await fount().resolve('config', 'myScope');
```

### resolveAll

Resolve multiple dependencies at once:

```typescript
const { host, port } = await fount().resolveAll(['host', 'port']);

// Across namespaces
const results = await fount().resolveAll(['db.host', 'cache.host']);
```

### inject

Resolve dependencies and pass them to a function:

```typescript
// With explicit dependency list
const result = await fount().inject(['host', 'port'], (host, port) => {
  return `${host}:${port}`;
});

// With inferred dependencies
const result = await fount().inject((host, port) => {
  return `${host}:${port}`;
});

// With scope
const result = await fount().inject(['config'], (config) => {
  return config.value;
}, 'myScope');
```

### Deferred Resolution

A key feature of fount is that async methods wait for dependencies to be registered:

```typescript
// Start resolving before the dependency exists
const valuePromise = fount().resolve('laterValue');

// Register the dependency later
setTimeout(() => {
  fount().register('laterValue', 42);
}, 1000);

// The promise resolves once the dependency is registered
const value = await valuePromise; // 42
```

This also works with dependency chains:

```typescript
// Register factories that depend on unregistered values
fount().registerFactory('doubled', ['base'], (base) => base * 2);
fount().registerFactory('result', ['doubled'], (doubled) => doubled + 10);

// Start resolution
const resultPromise = fount().resolve('result');

// Register the base value later
setTimeout(() => {
  fount().register('base', 5);
}, 100);

const result = await resultPromise; // 20 (5 * 2 + 10)
```

## Synchronous Methods

These methods return values immediately and assume no promises in the dependency chain.

> **Warning**: If a promise is encountered in the dependency chain, synchronous methods will not resolve it properly.

### get

Get a dependency value synchronously:

```typescript
const port = fount().get('port');

// With scope
const value = fount().get('config', 'myScope');

// Multiple values
const { host, port } = fount().getAll(['host', 'port']);
```

### invoke

Invoke a function with resolved dependencies synchronously:

```typescript
const result = fount().invoke(['host', 'port'], (host, port) => {
  return `${host}:${port}`;
});

// With inferred dependencies
const result = fount().invoke((host, port) => {
  return `${host}:${port}`;
});
```

## Checking Resolution

Use `canResolve` to check if dependencies can be resolved without waiting:

```typescript
if (fount().canResolve('myKey')) {
  const value = fount().get('myKey');
}

// Check multiple keys
if (fount().canResolve(['key1', 'key2'])) {
  const values = fount().getAll(['key1', 'key2']);
}
```

## Configuration

Configure multiple containers and values at once:

```typescript
fount({
  default: {
    host: 'localhost',
    port: 8080
  },
  database: {
    host: 'db.example.com',
    port: 5432,
    pool: {
      factory: () => createPool()
    }
  },
  cache: {
    ttl: 3600,
    maxSize: {
      scoped: () => calculateMaxSize()
    }
  }
});
```

Values can be:
- Plain values (registered as static)
- Objects with `factory` key (registered as factory lifecycle)
- Objects with `scoped` key (registered as scoped lifecycle)
- Objects with `static` key (registered as static lifecycle)

## Utility Methods

### Key Lists

```typescript
// All keys across all namespaces
const allKeys = fount.allKeys();

// Keys in a specific namespace
const keys = fount('myNamespace').keys();
```

### Namespaces

```typescript
const namespaces = fount.namespaces();
```

### Purging

```typescript
// Remove everything
fount.purgeAll();

// Remove all keys from the default namespace
fount().purge();

// Remove all keys from a specific namespace
fount('myNamespace').purge();
```

### Diagnostics

```typescript
// Log the current state of all containers
fount.log();
```

## TypeScript Support

Fount is written in TypeScript and exports its types:

```typescript
import { fount, Fount, ContainerApi } from 'fount';

// The main fount export
const f: Fount = fount;

// Container API returned when calling fount()
const container: ContainerApi = fount();
```

## Testing

```bash
# Run tests once
npm test

# Run tests in watch mode
npm run test:watch
```

---
_Source: https://npm.io/package/fount · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
