Skip to content

Comparisons

Comparisons between ABIType's features and features from similar libraries

No other library does what ABIType does (inferring TypeScript types from ABIs and EIP-712 Typed Data), but there are some similarities with other libraries. This page compares ABIType to other libraries that are similar in some way.

Comparisons strive to be as accurate and as unbiased as possible. If you use any of these libraries and feel the information could be improved, feel free to suggest changes.

TypeChain

TypeChain is a command-line tool that generates types and runtime wrappers for popular libraries at build time. People often use the generated types to cast values (e.g. new Contract(…) as TypeChainType). ABIType is a TypeScript library that infers static types from any ABI using type-level programming.

Below is a comparison of the libraries's type-level features:

TypeChainABIType
Lifecycle StepGenerated at build timeInferred at compile time
ABI SourcePath(s) to CLI commandDirectly reference in code
Type GenerationIterates through ABIs and builds stringsStatic from type-level

ethers.js

ethers.js is a JavaScript library for interacting with Ethereum. Among other features, it has utilities for working with human-readable ABIs. In addition to runtime functions, ABIType also has type utilities for working with human-readable ABIs.

Below is a comparison of the runtime functions from ethers.js and ABIType for parsing and formatting human-readable ABIs.

Interface versus parseAbi

Parses a human-readable ABI into a JSON ABI.

import { 
function parseAbi<const TSignatures extends readonly string[]>(signatures: TSignatures['length'] extends 0 ? Error<'At least one signature required'> : Signatures<TSignatures> extends TSignatures ? TSignatures : Signatures<TSignatures>): ParseAbi<TSignatures>

Parses human-readable ABI into JSON Abi

parseAbi
} from 'abitype'
const
const abi: readonly [{ readonly name: "name"; readonly type: "function"; readonly stateMutability: "nonpayable"; readonly inputs: readonly [{ readonly type: "tuple"; readonly components: readonly [{ readonly type: "string"; readonly name: "name"; }, { ...; }]; readonly name: "foo"; }, { ...; }]; readonly outputs: readonly []; }, { ...; }]
abi
=
parseAbi<["function name((string name, uint256 age) foo, uint256 tokenId)", "event Foo(address indexed bar)"]>(signatures: ["function name((string name, uint256 age) foo, uint256 tokenId)", "event Foo(address indexed bar)"]): readonly [...]

Parses human-readable ABI into JSON Abi

parseAbi
([
'function name((string name, uint256 age) foo, uint256 tokenId)', 'event Foo(address indexed bar)', ])
const abi: readonly [{ readonly name: "name"; readonly type: "function"; readonly stateMutability: "nonpayable"; readonly inputs: readonly [{ readonly type: "tuple"; readonly components: readonly [{ readonly type: "string"; readonly name: "name"; }, { ...; }]; readonly name: "foo"; }, { ...; }]; readonly outputs: readonly []; }, { ...; }]
abi
  • ABIType returns inferred ABI, while ethers.js just returns readonly Fragment[]
  • ABIType supports structs as signatures and inline tuples (e.g. (string name, uint256 age)).
  • ethers.js does not support struct signatures, but does support inline tuples with the optional tuple prefix keyword.
  • ABIType supports mixed named and unnamed parameters, while ethers.js only supports either all named or all unnamed parameters.

Fragment versus parseAbiItem

Parses a human-readable ABI item into a JSON ABI item.

import { 
function parseAbiItem<TSignature extends string | readonly string[] | readonly unknown[]>(signature: Narrow<TSignature> & ((TSignature extends string ? string extends TSignature ? unknown : Signature<TSignature> : never) | (TSignature extends readonly string[] ? TSignature extends readonly [] ? Error<'At least one signature required.'> : string[] extends TSignature ? unknown : Signatures<TSignature> : never))): ParseAbiItem<TSignature>

Parses human-readable ABI item (e.g. error, event, function) into Abi item

parseAbiItem
} from 'abitype'
const
const abiItem: { readonly name: "name"; readonly type: "function"; readonly stateMutability: "nonpayable"; readonly inputs: readonly [{ readonly type: "tuple"; readonly components: readonly [{ readonly type: "string"; readonly name: "name"; }, { ...; }]; readonly name: "foo"; }, { ...; }]; readonly outputs: readonly []; }
abiItem
=
parseAbiItem<"function name((string name, uint256 age) foo, uint256 tokenId)">(signature: "function name((string name, uint256 age) foo, uint256 tokenId)"): { readonly name: "name"; readonly type: "function"; readonly stateMutability: "nonpayable"; readonly inputs: readonly [...]; readonly outputs: readonly []; }

Parses human-readable ABI item (e.g. error, event, function) into Abi item

parseAbiItem
(
'function name((string name, uint256 age) foo, uint256 tokenId)', )

Benchmarks

 pnpm bench src/human-readable/parseAbiItem.bench.ts
 
 Parse ABI item (3) 1716ms
  name              hz     min     max    mean     p75     p99    p995    p999     rme  samples
· abitype   597,815.38  0.0015  0.3760  0.0017  0.0016  0.0022  0.0022  0.0031  ±0.58%   298908   fastest
· ethers@5   83,313.74  0.0114  0.2662  0.0120  0.0119  0.0130  0.0141  0.0401  ±0.45%    41657  
· ethers@6   39,887.50  0.0233  0.3942  0.0251  0.0248  0.0308  0.0365  0.1979  ±0.43%    19944   slowest
 
Summary
abitype - src/human-readable/parseAbiItem.bench.ts > comparison
  7.18x faster than ethers@5
  14.99x faster than ethers@6

ParamType versus parseAbiParameter

Parses a human-readable ABI parameter into a JSON ABI parameter.

import { 
function parseAbiParameter<TParam extends string | readonly string[] | readonly unknown[]>(param: Narrow<TParam> & ((TParam extends string ? TParam extends '' ? Error<'Empty string is not allowed.'> : unknown : never) | (TParam extends readonly string[] ? TParam extends readonly [] ? Error<'At least one parameter required.'> : string[] extends TParam ? unknown : unknown : never))): ParseAbiParameter<TParam>

Parses human-readable ABI parameter into AbiParameter

parseAbiParameter
} from 'abitype'
const
const abiParameter: { readonly type: "string"; readonly name: "foo"; }
abiParameter
=
parseAbiParameter<"string foo">(param: "string foo"): { readonly type: "string"; readonly name: "foo"; }

Parses human-readable ABI parameter into AbiParameter

parseAbiParameter
('string foo')

Benchmarks

 pnpm bench src/human-readable/parseAbiParameter.bench.ts
 
 Parse basic ABI Parameter (3) 2358ms
  name                hz     min     max    mean     p75     p99    p995    p999     rme  samples
· abitype   4,073,274.42  0.0001  1.0815  0.0002  0.0003  0.0003  0.0003  0.0005  ±0.52%  2036638   fastest
· ethers@6    288,007.56  0.0032  1.5593  0.0035  0.0034  0.0039  0.0058  0.0082  ±0.75%   144004   slowest
· ethers@5    507,627.43  0.0018  0.6730  0.0020  0.0020  0.0022  0.0023  0.0027  ±0.43%   253814  
 
Summary
abitype - src/human-readable/parseAbiParameter.bench.ts > Parse basic ABI Parameter
  8.02x faster than ethers@5
  14.14x faster than ethers@6

Interface.format versus formatAbi

Format JSON ABI into human-readable ABI.

import { 
function formatAbi<const TAbi extends Abi | readonly unknown[]>(abi: TAbi): FormatAbi<TAbi>

Parses JSON ABI into human-readable ABI

formatAbi
} from 'abitype'
const
const abi: readonly ["function name((string name, uint256 age) foo, uint256 tokenId)", "event Foo(address indexed bar)"]
abi
=
formatAbi<readonly [{ readonly type: "function"; readonly name: "name"; readonly stateMutability: "nonpayable"; readonly inputs: readonly [{ readonly type: "tuple"; readonly name: "foo"; readonly components: readonly [{ readonly type: "string"; readonly name: "name"; }, { ...; }]; }, { ...; }]; readonly outputs: readonly []; }, { ...; }]>(abi: readonly [...]): readonly [...]

Parses JSON ABI into human-readable ABI

formatAbi
([
{
type: "function"
type
: 'function',
name: "name"
name
: 'name',
stateMutability: "nonpayable"
stateMutability
: 'nonpayable',
inputs: readonly [{ readonly type: "tuple"; readonly name: "foo"; readonly components: readonly [{ readonly type: "string"; readonly name: "name"; }, { readonly type: "uint256"; readonly name: "age"; }]; }, { readonly type: "uint256"; readonly name: "tokenId"; }]
inputs
: [
{
type: "tuple"
type
: 'tuple',
name: "foo"
name
: 'foo',
components: readonly [{ readonly type: "string"; readonly name: "name"; }, { readonly type: "uint256"; readonly name: "age"; }]
components
: [
{
type: "string"
type
: 'string',
name: "name"
name
: 'name' },
{
type: "uint256"
type
: 'uint256',
name: "age"
name
: 'age' },
], }, {
type: "uint256"
type
: 'uint256',
name: "tokenId"
name
: 'tokenId' },
],
outputs: readonly []
outputs
: [],
}, {
type: "event"
type
: 'event',
name: "Foo"
name
: 'Foo',
inputs: readonly [{ readonly type: "address"; readonly name: "bar"; readonly indexed: true; }]
inputs
: [{
type: "address"
type
: 'address',
name: "bar"
name
: 'bar',
indexed: true
indexed
: true }],
}, ])
const abi: readonly ["function name((string name, uint256 age) foo, uint256 tokenId)", "event Foo(address indexed bar)"]
abi

ABIType returns inferred human-readable ABI, while ethers.js just returns string[].

Benchmarks

 pnpm bench src/human-readable/formatAbi.bench.ts
 
 Format ABI (3) 2068ms
· abitype   1,687,145.72 ops/sec ±0.39% (843573 samples) fastest
· ethers@5    117,287.14 ops/sec ±0.36% ( 58644 samples)
· ethers@6     46,075.42 ops/sec ±0.37% ( 23038 samples) slowest
 
Summary
abitype - src/human-readable/formatAbi.bench.ts > Format ABI
  14.38x faster than ethers@5
  36.62x faster than ethers@6

Fragment.format versus formatAbiItem

Formats a JSON ABI item into a human-readable ABI item.

import { 
function formatAbiItem<const TAbiItem extends AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive>(abiItem: TAbiItem): FormatAbiItem<TAbiItem>

Formats ABI item (e.g. error, event, function) into human-readable ABI item

formatAbiItem
} from 'abitype'
const
const abiItem: "function foo(string bar, string baz)"
abiItem
=
formatAbiItem<{ readonly type: "function"; readonly name: "foo"; readonly stateMutability: "nonpayable"; readonly inputs: readonly [{ readonly type: "string"; readonly name: "bar"; }, { readonly type: "string"; readonly name: "baz"; }]; readonly outputs: readonly []; }>(abiItem: { ...; }): "function foo(string bar, string baz)"

Formats ABI item (e.g. error, event, function) into human-readable ABI item

formatAbiItem
({
type: "function"
type
: 'function',
name: "foo"
name
: 'foo',
stateMutability: "nonpayable"
stateMutability
: 'nonpayable',
inputs: readonly [{ readonly type: "string"; readonly name: "bar"; }, { readonly type: "string"; readonly name: "baz"; }]
inputs
: [
{
type: "string"
type
: 'string',
name: "bar"
name
: 'bar' },
{
type: "string"
type
: 'string',
name: "baz"
name
: 'baz' },
],
outputs: readonly []
outputs
: [],
})
const abiItem: "function foo(string bar, string baz)"
abiItem

ABIType returns inferred human-readable ABI item, while ethers.js just returns string.

Benchmarks

 pnpm bench src/human-readable/formatAbi.bench.ts
 
 Format basic ABI function (3) 2534ms
· abitype   4,833,836.91 ops/sec ±0.89% (2416919 samples) fastest
· ethers@6    123,697.64 ops/sec ±0.32% (  61849 samples) slowest
· ethers@5    343,959.66 ops/sec ±0.33% ( 171980 samples)
 
Summary
abitype - src/human-readable/formatAbiItem.bench.ts > Format basic ABI function
  14.05x faster than ethers@5
  39.08x faster than ethers@6
 

ParamType.format versus formatAbiParameter

Formats JSON ABI parameter to human-readable ABI parameter.

import { 
function formatAbiParameter<const TAbiParameter extends AbiParameter | AbiEventParameter>(abiParameter: TAbiParameter): FormatAbiParameter<TAbiParameter>

Formats AbiParameter to human-readable ABI parameter.

formatAbiParameter
} from 'abitype'
const
const result: "string foo"
result
=
formatAbiParameter<{ readonly type: "string"; readonly name: "foo"; }>(abiParameter: { readonly type: "string"; readonly name: "foo"; }): "string foo"

Formats AbiParameter to human-readable ABI parameter.

formatAbiParameter
({
type: "string"
type
: 'string',
name: "foo"
name
: 'foo' })

ABIType returns inferred human-readable ABI parameter, while ethers.js just returns string

Benchmarks

 pnpm bench src/human-readable/formatAbiParameter.bench.ts
 
 Format basic ABI Parameter (3) 5043ms
· abitype   10,550,231.55 ops/sec ±0.63% (5275116 samples) fastest
· ethers@6     398,639.32 ops/sec ±0.40% ( 199320 samples) slowest
· ethers@5   1,041,080.97 ops/sec ±0.45% ( 520541 samples)
 
Summary
abitype - src/human-readable/formatAbiParameter.bench.ts > Format basic ABI Parameter
  10.41x faster than ethers@5
  28.57x faster than ethers@6