Type-safe tools for reading, writing, and building applications on ENS.
- Unified ENS actions across supported deployments and migration states
- Names, resolver records, registration, renewals, migration, wrapping, DNS, and reverse resolution
- Automatic contract routing with typed results and errors
- Batched reads and wallet-aware write workflows
- Bring your own viem clients or Wagmi config
- Framework-independent actions, a grouped SDK client, and reactive React hooks
| Package | Description |
|---|---|
@ensforge/contracts |
Contract ABIs, deployment addresses, and shared interfaces |
@ensforge/core |
Framework-independent ENS actions and utilities |
@ensforge/sdk |
Config-bound client with actions grouped by capability |
@ensforge/react |
Providers, queries, mutations, and cache primitives |
Install the high-level SDK:
pnpm add @ensforge/sdk effect@rc viemCreate a client and call any grouped action:
import { Ensforge } from "@ensforge/sdk";
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
const sdk = new Ensforge({
network: "mainnet",
publicClient: createPublicClient({
chain: mainnet,
transport: http(),
}),
});
const owner = await sdk.name.getOwner({ name: "ens.eth" });
const avatar = await sdk.records.getAvatar({ name: "ens.eth" });Use @ensforge/core when you prefer standalone actions:
import { createConfig, getAddress, getOwner, readBatch } from "@ensforge/core";
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
const publicClient = createPublicClient({ chain: mainnet, transport: http() });
const config = createConfig({ network: "mainnet", publicClient });
const profile = await readBatch(config, {
owner: getOwner.request({ name: "ens.eth" }),
address: getAddress.request({ name: "ens.eth" }),
});For React applications, pass an SDK instance or the same configuration to EnsforgeProvider and
use typed hooks:
import { EnsforgeProvider, useOwner } from "@ensforge/react";
const Profile = () => {
const owner = useOwner({ name: "ens.eth" });
return <span>{owner.data?.owner}</span>;
};
const App = () => (
<EnsforgeProvider sdk={sdk}>
<Profile />
</EnsforgeProvider>
);The monorepo also contains private development packages:
packages/
test-env/ Private deterministic ENS integration environment
template/ Starter for future packages
Requires Node.js 24+ and pnpm 11.10.0.
pnpm install
pnpm build
pnpm checkpnpm check:sdk-types compiles a representative SDK consumer and enforces declaration,
instantiation, and memory budgets for the public type surface.
Package boundaries resolve through generated declarations during editor and type-checking sessions.
Run pnpm build after cloning, or keep pnpm dev running while changing multiple packages, so
downstream packages see current declarations without loading every dependency's source graph.
See CONTRIBUTING.md for the complete development, testing, documentation, and changeset workflow.
Apache-2.0