Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/fig-outlined.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/fig.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: pnpm

- name: Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20
22
14 changes: 0 additions & 14 deletions .versionrc

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Corentin THOMASSET
Copyright (c) 2025 Corentin THOMASSET

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
65 changes: 50 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,48 @@
# Figue
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="./.github/fig.png">
<source media="(prefers-color-scheme: light)" srcset="./.github/fig-outlined.png">
<img src="./.github/fig.png" alt="Figue" width="200" />
</picture>
</p>

[![ci](https://github.com/CorentinTh/figue/actions/workflows/ci.yml/badge.svg)](https://github.com/CorentinTh/figue/actions/workflows/ci.yml)
<h1 align="center">
Figue - Application configuration management
</h1>
<p align="center">
The modern way to handle and validate your application configuration with any standard-schema-compliant validation library.
</p>

> Platform agnostic configuration management library, with environmental variables and validation, like [convict](https://github.com/mozilla/node-convict/tree/master/packages/convict) but simpler, cross env and using [zod schemas](https://github.com/colinhacks/zod).

## Introduction

Figue is a modern configuration management library for Node.js. It is designed to be easy to use, flexible, it can used in any environment, and can be used with any standard-schema-compliant validation library, like [zod](https://github.com/colinhacks/zod) or [valibot](https://github.com/valibot/valibot).

Think of it as a modern version of [convict](https://github.com/mozilla/node-convict/tree/master/packages/convict) but simpler, cross env and using battle tested validation libraries.

## Features

- Environment variables support
- Validation with any standard-schema-compliant validation library
- Flat object support
- Multiple sources of configuration
- Type-safe configuration
- Composable configuration

## Usage

Install package:

```sh
# pnpm
pnpm install figue

# npm
npm install figue zod
npm install figue

# yarn
yarn install figue zod
yarn install figue

# pnpm
pnpm install figue zod
```

Import:
Expand All @@ -33,40 +59,42 @@ const { defineConfig } = require('figue');

### Basic example

Use the `defineConfig` function to define your configuration, here with [valibot](https://github.com/valibot/valibot):

```typescript
import { defineConfig } from 'figue';
import { z } from 'zod';
import * as v from 'valibot';

const { config } = defineConfig(
{
env: {
doc: 'Application current environment',
default: 'development',
schema: z.enum(['development', 'production', 'test']),
schema: v.picklist(['development', 'production', 'test']),
env: 'NODE_ENV',
},
port: {
doc: 'Application port to listen',
schema: z.coerce.number().int().positive(),
schema: v.pipe(v.union([v.number(), v.string()]), v.transform(Number)),
default: 3000,
env: 'PORT',
},
db: {
host: {
doc: 'Database server url',
schema: z.string().url(),
default: 'localhost',
schema: v.pipe(v.string(), v.url()),
default: 'http://localhost:5432',
env: 'APP_DB_HOST',
},
username: {
doc: 'Database server username',
schema: z.string(),
schema: v.string(),
default: 'pg',
env: 'APP_DB_USERNAME',
},
password: {
doc: 'Database server password',
schema: z.string(),
schema: v.string(),
default: '',
env: 'APP_DB_PASSWORD',
},
Expand All @@ -89,6 +117,10 @@ console.log(config);
// }
```

You can see more examples in the [demo](./demo) folder.
- Figue with zod: [demo/figue-zod.ts](./demo/figue-zod.ts)
- Figue with valibot: [demo/figue-valibot.ts](./demo/figue-valibot.ts)

### Load environnement

Use the `envSource` key of the second argument of `defineConfig` to specify the source of the environment variables:
Expand Down Expand Up @@ -229,7 +261,10 @@ Convict is meant to be used in node based environnement, it needs to have access

## Credits

Coded with ❤️ by [Corentin Thomasset](//corentin-thomasset.fr).
This project is crafted with ❤️ by [Corentin Thomasset](https://corentin.tech).
If you find this project helpful, please consider [supporting my work](https://buymeacoffee.com/cthmsst).

Fig icons created by <a href="https://www.flaticon.com/free-icons/fig" title="fig icons">Freepik - Flaticon</a>

## License

Expand Down
11 changes: 0 additions & 11 deletions build.config.ts

This file was deleted.

44 changes: 44 additions & 0 deletions demo/figue-valibot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { defineConfig } from 'figue';
import * as v from 'valibot';

const { config } = defineConfig(
{
env: {
doc: 'Application current environment',
default: 'development',
schema: v.picklist(['development', 'production', 'test']),
env: 'NODE_ENV',
},
port: {
doc: 'Application port to listen',
schema: v.pipe(v.union([v.number(), v.string()]), v.transform(Number)),
default: 3000,
env: 'PORT',
},
db: {
host: {
doc: 'Database server url',
schema: v.pipe(v.string(), v.url()),
default: 'http://localhost:5432',
env: 'APP_DB_HOST',
},
username: {
doc: 'Database server username',
schema: v.string(),
default: 'pg',
env: 'APP_DB_USERNAME',
},
password: {
doc: 'Database server password',
schema: v.string(),
default: '',
env: 'APP_DB_PASSWORD',
},
},
},
{
envSource: process.env,
},
);

console.log(config);
44 changes: 44 additions & 0 deletions demo/figue-zod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { defineConfig } from 'figue';
import { z } from 'zod';

const { config } = defineConfig(
{
env: {
doc: 'Application current environment',
default: 'development',
schema: z.enum(['development', 'production', 'test']),
env: 'NODE_ENV',
},
port: {
doc: 'Application port to listen',
schema: z.coerce.number(),
default: 3000,
env: 'PORT',
},
db: {
host: {
doc: 'Database server url',
schema: z.url(),
default: 'http://localhost:5432',
env: 'APP_DB_HOST',
},
username: {
doc: 'Database server username',
schema: z.string(),
default: 'pg',
env: 'APP_DB_USERNAME',
},
password: {
doc: 'Database server password',
schema: z.string(),
default: '',
env: 'APP_DB_PASSWORD',
},
},
},
{
envSource: process.env,
},
);

console.log(config);
3 changes: 1 addition & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export default antfu({

rules: {
// To allow export on top of files
'ts/no-use-before-define': ['error', { allowNamedExports: true, functions: false }],
'curly': ['error', 'all'],
'vitest/consistent-test-it': ['error', { fn: 'test' }],
'ts/consistent-type-definitions': ['error', 'type'],
Expand All @@ -20,5 +19,5 @@ export default antfu({
}],
},

ignores: ['README.md'],
ignores: ['README.md', 'demo/*'],
});
42 changes: 21 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "module",
"version": "2.2.3",
"private": false,
"packageManager": "pnpm@9.0.6",
"packageManager": "pnpm@10.13.1",
"description": "Platform agnostic configuration management library, with environmental variables and validation, like convict but cross-env and zod schemas",
"author": "Corentin Th <corentin.thomasset74+npm@gmail.com> (https://github.com/CorentinTh)",
"license": "MIT",
Expand All @@ -25,45 +25,45 @@
"vite",
"browser",
"import",
"meta"
"meta",
"standard-schema",
"zod",
"valibot"
],
"sideEffects": false,
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
".": "./dist/index.js",
"./package.json": "./package.json"
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "unbuild",
"build": "tsdown",
"dev": "vitest dev",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"prepack": "unbuild",
"prepack": "pnpm build",
"release": "bumpp && pnpm publish",
"test": "vitest run",
"test:watch": "vitest watch",
"typecheck": "tsc --noEmit"
},
"peerDependencies": {
"zod": "^3.22.4"
},
"dependencies": {
"zod": "^3.22.4"
"@standard-schema/spec": "^1.0.0"
},
"devDependencies": {
"@antfu/eslint-config": "^3.5.0",
"bumpp": "^9.5.2",
"eslint": "^9.10.0",
"standard-version": "^9.5.0",
"typescript": "^5.4.5",
"unbuild": "^2.0.0",
"vitest": "^1.6.0"
"@antfu/eslint-config": "^5.0.0",
"@vitest/coverage-v8": "3.2.4",
"bumpp": "^10.2.0",
"eslint": "^9.32.0",
"tsdown": "^0.13.0",
"typescript": "^5.8.3",
"valibot": "^1.1.0",
"vitest": "^3.2.4",
"zod": "^4.0.10"
}
}
Loading