Skip to content

Notable Methods & Exports

Beyond the high-level bundler plugins, Tevm exposes several internal utility methods and functions for advanced use cases. These are useful if you're building custom bundling workflows, debugging compilation issues, or extending Tevm's functionality.

Core Bundler (@tevm/base-bundler)

The base bundler handles the complete process of transforming Solidity files into JavaScript/TypeScript modules:

import { bundler } from '@tevm/base-bundler'
import { createCache } from '@tevm/bundler-cache'
import { createSolc } from '@tevm/solc'
import { loadConfig } from '@tevm/config'
 
// Create a bundler instance
const tevmBundler = bundler(
  config,        // from loadConfig()
  console,       // logger
  fileAccessObj, // file system access
  solcInstance,  // from createSolc()
  cacheInstance, // from createCache()
)
 
// Convert a Solidity file to TypeScript
const { code, modules } = await tevmBundler.resolveTsModule(
  'MyContract.s.sol',
  process.cwd(),
  false, // includeAst
  true   // includeBytecode
)

The bundler() factory creates an object with methods for different output formats:

  • resolveTsModule - Generates TypeScript
  • resolveEsmModule - Generates ES modules
  • resolveCjsModule - Generates CommonJS
  • resolveDts - Generates TypeScript declarations

Each method also has a synchronous version with Sync suffix (e.g., resolveTsModuleSync).

Source: bundler.js

Import Resolution (@tevm/resolutions)

The resolutions package provides tools for parsing and resolving Solidity import statements:

import { moduleFactory, resolveImports } from '@tevm/resolutions'
 
// Find all imports in a Solidity file
const imports = await resolveImports(
  '/path/to/Contract.sol',     // absolute path
  contractSourceCode,          // raw source code 
  { '@openzeppelin/': 'node_modules/@openzeppelin/' }, // remappings
  ['lib', 'node_modules'],     // library search paths
  false                        // async mode
)
 
// Build a module dependency graph
const modules = await moduleFactory(
  '/path/to/Contract.sol',
  contractSourceCode,
  remappings,
  libraryPaths,
  fileAccessObj,
  false // async mode
)
  • resolveImports() - Parses import statements and resolves them to absolute file paths
  • moduleFactory() - Builds a complete dependency graph of Solidity modules

Source: moduleFactory.js | Source: resolveImports.js

Compilation (@tevm/compiler)

The compiler package handles the interaction with the Solidity compiler:

import { resolveArtifacts } from '@tevm/compiler'
 
// Compile a Solidity file and generate artifacts
const { artifacts, modules, asts } = await resolveArtifacts(
  'MyContract.s.sol', // entry point
  process.cwd(),      // base directory
  console,           // logger
  config,            // compiler config
  true,              // include AST
  true,              // include bytecode
  fileAccessObj,     // file access
  solcInstance       // solc compiler instance
)
 
// Result includes:
console.log(artifacts) // Contract artifacts with ABI, bytecode, etc.
console.log(modules)   // Module dependency graph
console.log(asts)      // Abstract Syntax Tree (if requested)
  • resolveArtifacts() - Compiles a Solidity file and its dependencies into ABI, bytecode, and AST
  • Also has a synchronous version: resolveArtifactsSync()

Source: resolveArtifacts.js

Caching (@tevm/bundler-cache)

The cache system improves build performance by storing compiled artifacts:

import { createCache } from '@tevm/bundler-cache'
 
// Create a cache instance
const cache = createCache(
  '.tevm',        // cache directory
  fileAccessObj,  // file system access
  process.cwd()   // current working directory
)
 
// Read/write artifacts and generated code
await cache.writeArtifacts(contractPath, compiledContracts)
const artifacts = await cache.readArtifacts(contractPath)
 
await cache.writeDts(contractPath, dtsContent)
const dts = await cache.readDts(contractPath)

The cache provides methods for reading and writing various types of files:

  • readArtifacts/writeArtifacts - Compiled contract artifacts (ABI, bytecode, etc.)
  • readDts/writeDts - TypeScript declaration files
  • readMjs/writeMjs - ESM JavaScript files
  • readCjs/writeCjs - CommonJS JavaScript files

Each method also has a synchronous version with Sync suffix.

Source: createCache.js

Configuration (@tevm/config)

The config package handles loading and merging configuration from various sources:

import { loadConfig } from '@tevm/config'
 
// Load configuration from tevm.config.json, tsconfig.json, foundry.toml, etc.
const config = await loadConfig(process.cwd())
 
console.log(config.remappings) // Merged remappings from all sources
console.log(config.libs)       // Library search paths
console.log(config.cacheDir)   // Cache directory
  • loadConfig() - Loads and merges configuration from multiple sources
  • Handles Foundry remappings, TypeScript config, and tevm.config.json

Source: loadConfig.js

Runtime (@tevm/runtime)

The runtime package generates the actual TypeScript/JavaScript code for compiled Solidity contracts:

import { generateTevmBody, generateTevmBodyDts } from '@tevm/runtime'
 
// Generate TypeScript implementation
const tsCode = generateTevmBody(
  'MyContract',         // contract name
  artifacts,            // compilation artifacts
  'tevm/contract',      // import path for createContract
  true,                 // include bytecode
)
 
// Generate TypeScript declaration
const dtsCode = generateTevmBodyDts(
  'MyContract',         // contract name
  artifacts,            // compilation artifacts
  'tevm/contract',      // import path for createContract
  true,                 // include bytecode
)
  • generateTevmBody() - Generates TypeScript/JavaScript implementation
  • generateTevmBodyDts() - Generates TypeScript declaration file (.d.ts)

Source: generateTevmBody.js | Source: generateTevmBodyDts.js

Creating a Custom Bundler

If you need to create a custom bundler pipeline, you can combine these utilities:

import { loadConfig } from '@tevm/config'
import { createSolc } from '@tevm/solc'
import { createCache } from '@tevm/bundler-cache'
import { bundler } from '@tevm/base-bundler'
import { resolveArtifacts } from '@tevm/compiler'
import fs from 'node:fs/promises'
 
// Step 1: Create a file access object
const fileAccess = {
  readFile: (path, enc) => fs.readFile(path, { encoding: enc }),
  writeFile: fs.writeFile,
  // Add other required methods...
}
 
// Step 2: Load configuration
const config = await loadConfig(process.cwd())
 
// Step 3: Create a cache
const cache = createCache('.tevm', fileAccess, process.cwd())
 
// Step 4: Create a solc instance
const solc = await createSolc()
 
// Step 5: Create a bundler
const myBundler = bundler(config, console, fileAccess, solc, cache)
 
// Step 6: Process a Solidity file
const result = await myBundler.resolveTsModule(
  'path/to/Contract.sol',
  process.cwd(),
  false,
  true
)
 
// Step 7: Use the generated code
console.log(result.code)  // TypeScript code for Contract

Further Reading