Creating Your Own Extension
This section will help you develop custom extensions for Scaffold-ETH 2, from simple additions to more complex modifications.
Video Guide: For a visual walkthrough of the extension development process, check out our YouTube tutorial.
Extension Structureโ
Before diving into the development process, let's understand the structure an extension should follow:
your-extension/
โโโ extension/
โ โโโ packages/
โ โ โโโ hardhat/ # (optional) For Hardhat-specific additions
โ โ โโโ foundry/ # (optional) For Foundry-specific additions
โ โ โโโ nextjs/
โ โ โโโ app/ # Any new pages/files
โ โ โ โโโ my-page
โ โ โ โโโ page.tsx
โ โ โ
โ โ โโโ ... # Any extra files/directories
โ โ โโโ package.json # Only include additional dependencies/scripts
โ โโโ package.json # Monorepo root package.json file
โ โโโ README.md # Instance README
โโโ README.md # Documentation for your extension
Developing a Simple Extensionโ
For simple extensions, such as adding a new page or component, you can directly create the extension structure without going through the full development workflow. Here's how:
- Create the directory structure as shown above.
- Add your new page or component in the appropriate directory.
- If needed, create a
package.json
with any additional dependencies. - Push your extension to GitHub.
That's it! Your simple extension is ready to be used by others via:
npx create-eth@latest -e {github-username}/{extension-repo-name}:{branch-name} # branch-name is optional
Developing an Advanced Extensionโ
Template Files and Argsโ
create-eth
uses a templating system for advanced extensions that need to modify existing files. This system allows you to inject content into specific files in the base project using the *.args.mjs
files.
Key points:
- They allow you to add specific content to files in the base project.
- Not all files can be modified this way. See TEMPLATE-FILES.md for a list of supported template files.
- To use a template file, create an
*.args.mjs
file in your extension having the same path structure as*.template.mjs
. For example, to add extra tab in the header, you'd createextension/packages/nextjs/components/Header.tsx.args.mjs
.
Advanced Development Workflowโ
When creating complex extensions, Scaffold-ETH 2 provides a set of tools to make the process easier. This workflow allows you to develop your extension in a full Scaffold-ETH 2 environment, test it locally, and then package it for distribution.
The workflow consists of two main parts:
Extension Development: This process helps you create your extension by modifying a base Scaffold-ETH 2 project.
Local Testing: This allows you to test your extension in a full Scaffold-ETH 2 environment before publishing.
Extension Development Utilityโ
Clone the
create-eth
Repository:git clone https://github.com/scaffold-eth/create-eth.git
cd create-eth
yarn installRun the Build Script:
yarn build:dev
This creates
cli.js
andcreate-extension.js
in thedist
directory.Run the CLI to Create a New Instance:
yarn cli
This command will create a new base instance, similar to running
npx create-eth@latest
.The name mentioned for the "Your project name" question will be used as the extension name. For example, if you provide
eip
as the value to the question, then the final extension name will beeip
.Develop the Extension:
- cd into the instance directory.
- Make necessary changes to the instance project.
- Commit the changes in the instance repository.
Create the Extension:
Return to the
create-eth
folder.yarn create-extension {projectName}
Example:
yarn create-extension eip
This command gathers all changes from the instance and creates an extension in the
create-eth/externalExtensions/${extensionName}
directory. This directory is the actual extension directory (notice it contains only extra files related to your extension changes), which can be published to GitHub and used by others.Publish the Extension:
- Go inside the extension directory.
- Push the extension to GitHub.
cd create-eth/externalExtensions/${extensionName}
git init
git add .
git commit -m "Initial commit of my extension"
git remote add origin <remote-repo-url>
git push -u origin mainNow other developers can use your published extension by using:
npx create-eth@latest -e {github-username}/{extension-repo-name}:{branch-name} # extension-branch-name is optional
Local Testing:โ
This phase allows you to test your extension locally and see how it works when used by other developers.
NOTE: If you've already published your extension to GitHub using the "Developing a Simple Extension" approach, make sure to clone that extension repository into the
create-eth/externalExtensions/
directory before proceeding with local testing.
Run the CLI in dev mode:
yarn cli -e {extensionName} --dev
Example:
yarn cli -e eip --dev
The
extensionName
should be present increate-eth/externalExtensions/${extensionName}
.Let's suppose you named your project "my-dev-instance". Then this
my-dev-instance
should contain all your extension changes.--dev
will symlink the extension to the instance project.Test and Tweak the Extension: Since the instance is symlinked with the extension, make necessary changes directly in the symlinked files within
my-dev-instance
, and changes should be automatically reflected in thecreate-eth/externalExtensions/${extensionName}
directory.Push the tweaked changes
- Go inside the extension directory.
- Push the changes to GitHub.
cd create-eth/externalExtensions/${extensionName}
git add .
git commit -m "some changes"
git pushNext time users call your extension via
npx create-eth@latest -e
, they will get the updated version.