diff --git a/internal/cli/server/chains/developer.go b/internal/cli/server/chains/developer.go
new file mode 100644
index 0000000000000000000000000000000000000000..61a8a186fdbdefd733ebe6882b3418a27083a572
--- /dev/null
+++ b/internal/cli/server/chains/developer.go
@@ -0,0 +1,47 @@
+package chains
+
+import (
+	"math/big"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/params"
+)
+
+// GetDeveloperChain returns the developer mode configs.
+func GetDeveloperChain(period uint64, faucet common.Address) *Chain {
+	// Override the default period to the user requested one
+	config := *params.AllCliqueProtocolChanges
+	config.Clique = &params.CliqueConfig{
+		Period: period,
+		Epoch:  config.Clique.Epoch,
+	}
+
+	// Assemble and return the chain having genesis with the
+	// precompiles and faucet pre-funded
+	return &Chain{
+		Hash:      common.Hash{},
+		NetworkId: 1337,
+		Genesis: &core.Genesis{
+			Config:     &config,
+			ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
+			GasLimit:   11500000,
+			BaseFee:    big.NewInt(params.InitialBaseFee),
+			Difficulty: big.NewInt(1),
+			Alloc: map[common.Address]core.GenesisAccount{
+				common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
+				common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
+				common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
+				common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
+				common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
+				common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
+				common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
+				common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
+				common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b
+				faucet:                           {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
+			},
+		},
+		Bootnodes: []string{},
+	}
+}
diff --git a/internal/cli/server/config.go b/internal/cli/server/config.go
index 457ee53aa9973c24443f4611d7db2b26603e28f7..98bafb5a92f92a7375637a4b2cce9779c873b4a1 100644
--- a/internal/cli/server/config.go
+++ b/internal/cli/server/config.go
@@ -91,6 +91,9 @@ type Config struct {
 
 	// GRPC has the grpc server related settings
 	GRPC *GRPCConfig
+
+	// Developer has the developer mode related settings
+	Developer *DeveloperConfig
 }
 
 type P2PConfig struct {
@@ -365,6 +368,14 @@ type AccountsConfig struct {
 	UseLightweightKDF bool `hcl:"use-lightweight-kdf,optional"`
 }
 
+type DeveloperConfig struct {
+	// Enabled enables the developer mode
+	Enabled bool `hcl:"dev,optional"`
+
+	// Period is the block period to use in developer mode
+	Period uint64 `hcl:"period,optional"`
+}
+
 func DefaultConfig() *Config {
 	return &Config{
 		Chain:     "mainnet",
@@ -486,6 +497,10 @@ func DefaultConfig() *Config {
 		GRPC: &GRPCConfig{
 			Addr: ":3131",
 		},
+		Developer: &DeveloperConfig{
+			Enabled: false,
+			Period:  0,
+		},
 	}
 }
 
@@ -573,6 +588,9 @@ func readConfigFile(path string) (*Config, error) {
 }
 
 func (c *Config) loadChain() error {
+	if c.Developer.Enabled {
+		return nil
+	}
 	chain, ok := chains.GetChain(c.Chain)
 	if !ok {
 		return fmt.Errorf("chain '%s' not found", c.Chain)
@@ -585,7 +603,7 @@ func (c *Config) loadChain() error {
 	}
 
 	// depending on the chain we have different cache values
-	if c.Chain != "mainnet" {
+	if c.Chain == "mainnet" {
 		c.Cache.Cache = 4096
 	} else {
 		c.Cache.Cache = 1024
@@ -599,8 +617,13 @@ func (c *Config) buildEth() (*ethconfig.Config, error) {
 		return nil, err
 	}
 	n := ethconfig.Defaults
-	n.NetworkId = c.chain.NetworkId
-	n.Genesis = c.chain.Genesis
+
+	// only update for non-developer mode as we don't yet
+	// have the chain object for it.
+	if !c.Developer.Enabled {
+		n.NetworkId = c.chain.NetworkId
+		n.Genesis = c.chain.Genesis
+	}
 	n.HeimdallURL = c.Heimdall.URL
 	n.WithoutHeimdall = c.Heimdall.Without
 
@@ -640,6 +663,27 @@ func (c *Config) buildEth() (*ethconfig.Config, error) {
 		}
 	}
 
+	// update for developer mode
+	if c.Developer.Enabled {
+		// get developer mode chain config
+		c.chain = chains.GetDeveloperChain(c.Developer.Period, n.Miner.Etherbase)
+
+		// update the parameters
+		n.NetworkId = c.chain.NetworkId
+		n.Genesis = c.chain.Genesis
+
+		// Update cache
+		c.Cache.Cache = 1024
+
+		// Update sync mode
+		c.SyncMode = "full"
+
+		// update miner gas price
+		if n.Miner.GasPrice == nil {
+			n.Miner.GasPrice = big.NewInt(1)
+		}
+	}
+
 	// discovery (this params should be in node.Config)
 	{
 		n.EthDiscoveryURLs = c.P2P.Discovery.DNS
@@ -788,6 +832,20 @@ func (c *Config) buildNode() (*node.Config, error) {
 		GraphQLVirtualHosts: c.JsonRPC.VHost,
 	}
 
+	// dev mode
+	if c.Developer.Enabled {
+		cfg.UseLightweightKDF = true
+
+		// disable p2p networking
+		c.P2P.NoDiscover = true
+		cfg.P2P.ListenAddr = ""
+		cfg.P2P.NoDial = true
+		cfg.P2P.DiscoveryV5 = false
+
+		// data dir
+		cfg.DataDir = ""
+	}
+
 	// enable jsonrpc endpoints
 	{
 		if c.JsonRPC.Http.Enabled {
diff --git a/internal/cli/server/flags.go b/internal/cli/server/flags.go
index 09e5a7bf780f42156c745b7fe6c1419fd6204df6..7403fc6c88206b912b86dce1eaecd33879f85eec 100644
--- a/internal/cli/server/flags.go
+++ b/internal/cli/server/flags.go
@@ -461,5 +461,17 @@ func (c *Command) Flags() *flagset.Flagset {
 		Usage: "Address and port to bind the GRPC server",
 		Value: &c.cliConfig.GRPC.Addr,
 	})
+
+	// developer
+	f.BoolFlag(&flagset.BoolFlag{
+		Name:  "dev",
+		Usage: "Enable developer mode with ephemeral proof-of-authority network and a pre-funded developer account, mining enabled",
+		Value: &c.cliConfig.Developer.Enabled,
+	})
+	f.Uint64Flag(&flagset.Uint64Flag{
+		Name:  "dev.period",
+		Usage: "Block period to use in developer mode (0 = mine only if transaction pending)",
+		Value: &c.cliConfig.Developer.Period,
+	})
 	return f
 }