diff --git a/docs/launch-arbitrum-chain/deploy/custom-genesis-state.mdx b/docs/launch-arbitrum-chain/deploy/custom-genesis-state.mdx
new file mode 100644
index 0000000000..f233117499
--- /dev/null
+++ b/docs/launch-arbitrum-chain/deploy/custom-genesis-state.mdx
@@ -0,0 +1,271 @@
+---
+title: 'Customize genesis state'
+description: 'How to configure your Arbitrum chain with a custom genesis state'
+author: gmetha2
+sme: Jason-W123
+content_type: how-to
+user_story: 'As an Arbitrum chain operator, I want to create a chain with a custom genesis state.'
+---
+
+Arbitrum chain operators are increasingly seeking to deploy chains with pre-existing state by loading an initial state in a file such as `genesis.json`. Specifically, chain operators want to predeploy smart contracts (like Gnosis Safe) to an Arbitrum chain so they exist from genesis, before any user interaction or post-launch governance.
+
+Initializing from a genesis state would be helpful in the following scenarios:
+
+1. Redeploying a new testnet with the pre-existing state if the current testnet is broken.
+2. Deploying additional sibling chains with pre-existing contracts.
+3. Simplifying self-serve backends for RaaSes, such that hundreds of testnets can be deployed with similar contracts.
+4. Reducing lift on third-party infrastructure teams to redeploy contracts for new chains.
+
+## Why should I use a custom genesis state?
+
+Using a custom genesis allows you to initialize a new blockchain with a customized genesis state and network configuration through the following options:
+
+- **Predeployed contracts**: standard chains start without any smart contracts. This feature allows you to preload contract bytecode in the very first block, so infrastructure is available at launch.
+- **Initial account state (allocations)**: you can pre-configure the ledger—including account balances and contract storage—before the network opens for transactions.
+- **Enable advanced features**: chain operators can use this feature to launch a chain with advanced customizations, such as [minting/burning gas tokens via third-party bridges](/launch-arbitrum-chain/chain-config/costs/configure-native-mint-burn.mdx) and compliance-focused transaction filtering.
+
+
+
+Preallocating account balances in the genesis state credits **ETH** (or your custom gas token) on your Arbitrum chain **without** depositing anything into the parent-chain bridge. The protocol does **not** require the bridge to hold ETH equal to the balances you preallocate, and there is no deploy-time check.
+
+If your chain will accept user deposits, a chain whose total preallocated balances exceed the bridge's backing is **insolvent from genesis**: withdrawals can fail once the bridge is drained. Only preallocate non-zero balances if you accept responsibility for backing them—for example, a private or test chain, or one where you deposit the equivalent amount into the bridge before opening it to users.
+
+
+
+## How to configure
+
+:::info Prerequisites
+
+
+
+- [Nitro contracts](https://github.com/OffchainLabs/nitro-contracts) >= v3.2
+ - first version to include full support for custom initialization in `genesis.json`
+- [Nitro node](/run-arbitrum-node/02-run-full-node.mdx) >= v3.11.0 is needed for using custom-genesis.
+- [Chain SDK](https://github.com/OffchainLabs/arbitrum-chain-sdk) >= xx.xx **or**
+ - Chain SDK only supports the standard `genesis.json` format, which includes the predeployed contracts.
+- [genesis-file-generator tool](https://hub.docker.com/r/offchainlabs/genesis-file-generator)
+
+ - If you want to customize the `genesis.json` file or pass accounts/custom chain config, you should use the `genesis-file-generator`.
+
+ **Note**: The chain configuration must be exactly the same at the string level, including the order of fields, potential whitespace, or special characters for the `serializedChainConfig` string
+
+:::
+
+### Use the Chain SDK
+
+The script completes the following automated steps:
+
+- Generates a standard `genesis.json` file with the pre-deployed contracts.
+- Calculates the `blockhash` and `sendRoot` hash and returns them for your use.
+- An option to deploy the rollup. You can either deploy the chain using the `genesis.json` above or use the output from the previous step to set up the chain separately.
+
+#### Core configuration ref
+
+The following is required to generate the `genesis.json` file:
+
+| Variable | Description |
+| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `CHAIN_ID` | The unique numeric identifier for your chain. |
+| `IS_ANYTRUST` | Whether the chain is an AnyTrust (`true`) or rollup (`false`). |
+| `ARBOS_VERSION` | The version of ArbOS to use for the genesis block. |
+| `CHAIN_OWNER` | The address that will have admin ownership of the deployed chain. |
+| `L1_BASE_FEE` | The initial L1 gas price (in wei) used to calibrate the chain initiation. |
+| `NITRO_NODE_IMAGE` | The Nitro node Docker image used for hashing and node operations. |
+| `ENABLE_NATIVE_TOKEN_SUPPLY` | Flag to launch your chain with native interop tokens as [minting/burning gas tokens via third-party bridges](/launch-arbitrum-chain/chain-config/costs/configure-native-mint-burn.mdx) via third-party protocols. |
+| `ENABLE_TRANSACTION_FILTERING` | Flag to launch your chain with protocol-level transaction filtering for regulatory or compliance purposes.
_**Note:** This feature requires ArbOS60 and Nitro node v3.10.0._ |
+
+#### Deployment configuration (optional)
+
+This step is only required if you choose to deploy the rollup to the parent chain (Step 3 below).
+
+| Variable | Description |
+| ------------------------ | ---------------------------------------------------------------------- |
+| DEPLOYER_PRIVATE_KEY | Private key of the account responsible for the rollup deployment. |
+| BATCH_POSTER_PRIVATE_KEY | Private key for the sequencer's batch-posting address. |
+| VALIDATOR_PRIVATE_KEY | Private key for the validator/bonder address |
+| PARENT_CHAIN_RPC | RPC endpoint for the parent chain (e.g., Arbitrum Sepolia or Ethereum) |
+
+
+
+`DEPLOYER_PRIVATE_KEY`, `BATCH_POSTER_PRIVATE_KEY`, and `VALIDATOR_PRIVATE_KEY` are secrets. Keep them in your `.env` (which should be `.gitignore`d) and never commit your `.env`—or any generated node configuration that embeds these keys—to version control.
+
+
+
+#### Execution steps
+
+1. Prepare the environment
+
+ - From the repository root, install dependencies and navigate to the generator directory.
+
+ ```shell
+ pnpm install && pnpm build
+
+ cd examples/generate-genesis-file && cp .env.example .env
+ ```
+
+2. Generate genesis
+
+ - Ensure your `.env` is configured and run the dev script.
+ - To preallocate custom accounts, set `CUSTOM_ALLOC_ACCOUNT_FILE=custom-alloc.json` in your `.env` and place the file (standard Geth `alloc` format) in the example directory. See the [`genesis-file-generator` section](#use-the-genesis-file-generator-tool) below for a sample, and review the solvency warning above before setting non-zero balances.
+ :::info Configuration
+
+ Double-check that your .env values match your intended chain specs before running the script.
+
+ :::
+
+3. Create rollup (optional)
+ - After generating the `genesis.json` file, the Chain SDK provides an option to deploy your rollup. Follow the prompts to continue or exit the process and deploy the rollup later.
+4. Configure and launch your node:
+ - Set up your node as usual (see the [full node guide](/run-arbitrum-node/02-run-full-node.mdx)), but include the following properties to point to your custom state:
+ - `--init.genesis-json-file=/path/to/genesis.json`: the path to your custom `genesis.json` file
+ - `--init.empty=false`: **(Required)** Forces the node to load the provided genesis file instead of initializing a blank state.
+5. Start your chain, with the correct preloaded state.
+
+
+
+Your custom genesis is loaded via the `--init.genesis-json-file` and `--init.empty=false` flags when you start the node—it is **not** read from `node-config.json`. If you generate your node configuration with the Chain SDK's `prepare-node-config`, it won't include these, so make sure to pass them on the command line.
+
+
+
+### Use the `genesis-file-generator` tool
+
+#### Environment variables reference (.env)
+
+These parameters define the identify of your chain
+
+| Variable | Description | Default |
+| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
+| `CHAIN_ID` | The unique numeric identifier for your new chain. | `31337` |
+| `IS_ANYTRUST` | Whether the chain is an AnyTrust (`true`) or a rollup (`false`). | `false` |
+| `ARBOS_VERSION` | The version of ArbOS to use for the genesis block. | `51` |
+| `CHAIN_OWNER` | The address that will have admin ownership of the deployed chain. | -- |
+| `L1_BASE_FEE` | The initial L1 gas price (in wei) used to calibrate the chain creation. | `1000000000` (1 gwei) |
+| `NITRO_NODE_IMAGE` | The Nitro node Docker image used for hashing and node operations. | -- |
+| `CUSTOM_ALLOC_ACCOUNT_FILE` | (optional) Path to a JSON file containing your own account balances, contract bytecode, and storage slots. The file should be in the the standard Geth `alloc` format. | `" "` (empty) |
+| `ENABLE_NATIVE_TOKEN_SUPPLY` | (optional) Set to `true` if you want to launch your chain with native interop tokens as [minting/burning gas tokens via third-party bridges](/launch-arbitrum-chain/chain-config/costs/configure-native-mint-burn.mdx) via third-party protocols. | `false` |
+| `LOAD_DEFAULT_PREDEPLOYS` | (optional) Set to `false` if you don't want the default predeploys. | `true` |
+| `ENABLE_TRANSACTION_FILTERING` | (optional) Set to `true` if you want to launch your chain with protocol-level transaction filtering for regulatory or compliance purposes.
_**Note:** This feature requires ArbOS60 and Nitro node v3.10.0._ | `false` |
+
+#### Execution process
+
+1. Prepare the genesis state
+
+ - Set up the `.env` file with the required parameters.
+ - Run the [`genesis-file-generator`](https://hub.docker.com/r/offchainlabs/genesis-file-generator/tags) Docker image to generate a `genesis.json` file with the required pre-deployed contracts and additional configurations.
+
+ ```shell
+ mkdir -p genesis
+
+ docker run --rm \
+ --env-file .env \
+ -v "$(pwd)/genesis":/app/genesis \
+ offchainlabs/genesis-file-generator:v0.0.3-rc-deffec7
+ ```
+
+ - You can also generate your own `genesis.json` file, but carefully read [this notice about the chain configuration property](https://github.com/OffchainLabs/genesis-file-generator#exclamation-important-note-about-the-chain-config-property) before proceeding with the next steps.
+
+ - To preallocate your own accounts—balances, contract bytecode, or storage slots—create a `custom-alloc.json` file (standard Geth `alloc` format) next to your `.env`, set `CUSTOM_ALLOC_ACCOUNT_FILE=custom-alloc.json` in the `.env`, and add a read-only bind mount for it to the `docker run` command:
+
+ ```shell
+ docker run --rm \
+ --env-file .env \
+ -v "$(pwd)/genesis":/app/genesis \
+ -v "$(pwd)/custom-alloc.json":/app/custom-alloc.json:ro \
+ offchainlabs/genesis-file-generator:v0.0.3-rc-deffec7
+ ```
+
+ Example `custom-alloc.json` (preallocates 1 ETH—review the solvency warning above before setting non-zero balances):
+
+ ```json
+ {
+ "0x299a89EE3Ee2BBC2cf9586ABd9AB1b57CF51B41F": { "balance": "0xde0b6b3a7640000" }
+ }
+ ```
+
+2. Generate the required hashes:
+
+ - After the `genesis.json` file is created, run the Nitro container to compute the genesis `blockhash` with the `genesis-generator` endpoint:
+
+ ```shell
+ source .env
+
+ docker run --rm \
+ -v "$(pwd)/genesis":/data/genesisDir \
+ --entrypoint genesis-generator \
+ "$NITRO_NODE_IMAGE" \
+ --genesis-json-file /data/genesisDir/genesis.json \
+ ```
+
+ - This bind-mounts the current directory into the container so it can read the `genesis.json` file generated in the previous step, and outputs the genesis `blockhash` and `sendRoot` hash. The `blockhash` and `sendRoot` hash will be logged as:
+
+ ```shell
+ genesis-hash-calculator | BlockHash: 0xd636d2cae7a75bf41f471639f1cbf98fe2a24216147792510e664a65496f27ed, SendRoot: 0x0000000000000000000000000000000000000000000000000000000000000000, Batch: 1, PosInBatch: 0
+ ```
+
+3. Deploy the rollup:
+ - Use the `blockhash`, `sendRoot`, `Batch`, and `PosInBatch` in the Chain SDK. The SDK will use these to generate the `assertion_hash` needed to register your rollup's core smart contracts on the parent chain.
+ - If you write your own deploy script with `@arbitrum/chain-sdk` (instead of the bundled `generate-genesis-file` example), make sure the rollup config includes the `dataCostEstimate` field. The bundled example sets it, and omitting it is a common cause of failed custom-genesis deployments.
+ ```javascript
+ const genesisAssertionState = {
+ globalState: {
+ bytes32Vals: [genesisBlockHash as `0x${string}`, sendRootHash as `0x${string}`] as [
+ `0x${string}`,
+ `0x${string}`,
+ ],
+ // Set inbox position to 1
+ u64Vals: [1n, 0n] as [bigint, bigint],
+ },
+ machineStatus: 1, // FINISHED
+ endHistoryRoot: toHex(0, { size: 32 }),
+ };
+ ```
+4. Configure and launch your node:
+ - Set up your node as usual (see the [full node guide](/run-arbitrum-node/02-run-full-node.mdx)), but include the following properties to point to your custom state:
+ - `--init.genesis-json-file=/path/to/genesis.json`: the path to your custom `genesis.json` file
+ - `--init.empty=false`: **(Required)** Forces the node to load the provided genesis file instead of initializing a blank state.
+5. Start your chain, with the correct preloaded state.
+
+### Pre-deployed contracts registry
+
+The following contracts are included by default in the standard `genesis.json` file. For the authoritative, maintained list—and details on how each contract is deployed—see the [`genesis-file-generator` README](https://github.com/OffchainLabs/genesis-file-generator#pre-deployed-contracts).
+
+| Category | Contract Name | Address | Note |
+| :------------------ | :----------------------------------- | :------------------------------------------- | :-------------------------------------- |
+| **Factories** | Safe Singleton Factory v1.0.43 | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` | Deterministic Proxy (Safe Key) |
+| | Create2Deployer | `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2` | CREATE (Deployer: `0x5542...`, Nonce 0) |
+| | CreateX v1.0.0 | `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed` | Pre-signed Transaction |
+| | Arachnid Proxy | `0x4e59b44847b379578588920cA78FbF26c0B4956C` | Deterministic Proxy (Arachnid) |
+| | Zoltu Deployment Proxy | `0x7A0D94F55792C434d74a40883C6ed8545E406D12` | Deterministic Proxy (Zoltu) |
+| | ERC-2470 Singleton Factory | `0xce0042B868300000d44A59004Da54A005ffdcf9f` | Singleton Factory (ERC-2470) |
+| **Safe v1.3.0** | GnosisSafe (Canonical) | `0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552` | Via Arachnid CREATE2 Proxy |
+| | GnosisSafe (EIP-155) | `0x69f4D1788e39c87893C980c06EdF4b7f686e2938` | Via Safe Singleton Factory |
+| | GnosisSafeL2 (Canonical) | `0x3e5c63644e683549055b9be8653de26e0b4cd36e` | Via Arachnid CREATE2 Proxy |
+| | GnosisSafeL2 (EIP-155) | `0xfb1bffC9d739B8D520DaF37dF666da4C687191EA` | Via Safe Singleton Factory |
+| | SafeProxyFactory (Canonical) | `0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2` | Via Arachnid CREATE2 Proxy |
+| | SafeProxyFactory (EIP-155) | `0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC` | Via Safe Singleton Factory |
+| | MultiSend v1.3.0 (Canonical) | `0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761` | Via Arachnid CREATE2 Proxy |
+| | MultiSend v1.3.0 (EIP-155) | `0x998739BFdAAdde7C933B942a68053933098f9EDa` | Via Safe Singleton Factory |
+| | MultiSendCallOnly v1.3.0 (Canonical) | `0x40A2aCCbd92BCA938b02010E17A5b8929b49130D` | Via Arachnid CREATE2 Proxy |
+| | MultiSendCallOnly v1.3.0 (EIP-155) | `0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B` | Via Safe Singleton Factory |
+| **Safe v1.4.1** | Safe | `0x41675C099F32341bf84BFc5382aF534df5C7461a` | Via Safe Singleton Factory |
+| | SafeL2 | `0x29fcB43b46531BcA003ddC8FCB67FFE91900C762` | Via Safe Singleton Factory |
+| | SafeProxyFactory | `0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67` | Via Safe Singleton Factory |
+| | MultiSend v1.4.1 | `0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526` | Via Safe Singleton Factory |
+| | MultiSendCallOnly v1.4.1 | `0x9641d764fc13c8B624c04430C7356C1C7C8102e2` | Via Safe Singleton Factory |
+| **ERC-4337 Core** | EntryPoint v0.6.0 | `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` | Standard v0.6 |
+| | SenderCreator v0.6.0 | `0x7fc98430eAEdbb6070B35B39D798725049088348` | Created during EP v0.6.0 deploy |
+| | EntryPoint v0.7.0 | `0x0000000071727De22E5E9d8BAf0edAc6f37da032` | Standard v0.7 |
+| | SenderCreator v0.7.0 | `0xEFC2c1444eBCC4Db75e7613d20C6a62fF67A167C` | Created during EP v0.7.0 deploy |
+| | EntryPoint v0.8.0 | `0x4337084d9e255ff0702461cf8895ce9e3b5ff108` | Standard v0.8 |
+| | SenderCreator v0.8.0 | `0x449ED7C3e6Fee6a97311d4b55475DF59C44AdD33` | Created during EP v0.8.0 deploy |
+| **Account Modules** | Safe Module Setup v0.3.0 | `0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47` | ERC-4337 Initializer |
+| | Safe 4337 Module v0.3.0 | `0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226` | Associated with Entrypoint v0.7.0 |
+| | Kernel v3.3 | `0xd6CEDDe84be40893d153Be9d467CD6aD37875b28` | Associated with Entrypoint v0.7.0 |
+| | KernelFactory v3.3 | `0x2577507b78c2008Ff367261CB6285d44ba5eF2E9` | Associated with Entrypoint v0.7.0 |
+| | MetaFactory v3.0 | `0xd703aaE79538628d27099B8c4f621bE4CCd142d5` | ZeroDev FactoryStaker |
+| | ECDSAValidator v3.1 | `0x845ADb2C711129d4f3966735eD98a9F09fC4cE57` | Compiled from commit 8f7fd99 |
+| **Infrastructure** | Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` | Pre-signed Transaction |
+| | ERC-1820 Registry | `0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24` | Pseudo-introspection Registry |
+| | Permit2 | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Uniswap Permit2 |
+| | EAS v1.4.0 | `0xF4C9CCaf46A866e2c12C5Bd95A39694718044444` | Ethereum Attestation Service |
+| | EAS SchemaRegistry | `0x822B0B93BE3f3B8Da35a2E90e877C01215be8506` | EAS Registry |
diff --git a/sidebars.js b/sidebars.js
index cf9e8a095d..36cd4b6939 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -420,6 +420,11 @@ const sidebars = {
id: 'launch-arbitrum-chain/deploy/canonical-factory-contracts',
label: `Canonical factory contracts`,
},
+ {
+ type: 'doc',
+ id: 'launch-arbitrum-chain/deploy/custom-genesis-state',
+ label: `Custom genesis state`,
+ },
{
type: 'doc',
id: 'launch-arbitrum-chain/deploy/configure-node',