or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app-lifecycle.mdconfiguration.mdcore.mddata-fetching.mdhead.mdindex.mdmodule-dev.mdnavigation.mdperformance.mdssr.mdstate.md

module-dev.mddocs/

0

# Module Development

1

2

Comprehensive utilities for developing Nuxt modules, including configuration, plugins, components, and build system integration. The Nuxt Kit provides everything needed to create powerful, reusable modules for the Nuxt ecosystem.

3

4

## Capabilities

5

6

### Module Definition

7

8

Define and create Nuxt modules with proper typing and lifecycle management.

9

10

```typescript { .api }

11

/**

12

* Define a Nuxt module with proper typing and lifecycle management

13

* @param definition - Module definition object or setup function

14

* @returns Configured Nuxt module

15

*/

16

function defineNuxtModule<OptionsT = Record<string, any>>(

17

definition: ModuleDefinition<OptionsT> | ModuleSetupFunction<OptionsT>

18

): NuxtModule<OptionsT>;

19

20

interface ModuleDefinition<T = Record<string, any>> {

21

/** Module metadata */

22

meta?: ModuleMeta;

23

/** Default options */

24

defaults?: T | ((nuxt: Nuxt) => T);

25

/** Module setup function */

26

setup?: ModuleSetupFunction<T>;

27

/** Module compatibility */

28

compatibility?: NuxtCompatibility;

29

}

30

31

interface ModuleMeta {

32

/** Module name */

33

name?: string;

34

/** Module version */

35

version?: string;

36

/** Module configuration key */

37

configKey?: string;

38

/** Module compatibility info */

39

compatibility?: NuxtCompatibility;

40

}

41

42

type ModuleSetupFunction<T = Record<string, any>> = (

43

resolvedOptions: T,

44

nuxt: Nuxt

45

) => void | Promise<void> | ModuleSetupReturn;

46

47

interface ModuleSetupReturn {

48

/** Timings for performance tracking */

49

timings?: {

50

setup?: number;

51

[key: string]: number | undefined;

52

};

53

}

54

```

55

56

**Usage Examples:**

57

58

```typescript

59

// Basic module definition

60

export default defineNuxtModule({

61

meta: {

62

name: "my-module",

63

configKey: "myModule"

64

},

65

defaults: {

66

enabled: true,

67

apiUrl: "/api"

68

},

69

setup(options, nuxt) {

70

console.log("Setting up my module with options:", options);

71

}

72

});

73

74

// Module with TypeScript options

75

interface MyModuleOptions {

76

enabled: boolean;

77

apiUrl: string;

78

features: {

79

auth: boolean;

80

analytics: boolean;

81

};

82

}

83

84

export default defineNuxtModule<MyModuleOptions>({

85

meta: {

86

name: "my-typed-module",

87

version: "1.0.0",

88

configKey: "myTypedModule"

89

},

90

defaults: {

91

enabled: true,

92

apiUrl: "/api",

93

features: {

94

auth: true,

95

analytics: false

96

}

97

},

98

setup(options, nuxt) {

99

if (!options.enabled) return;

100

101

// Module setup logic

102

addPlugin(createResolver(import.meta.url).resolve("./runtime/plugin"));

103

104

if (options.features.auth) {

105

addServerHandler({

106

route: "/api/auth/**",

107

handler: createResolver(import.meta.url).resolve("./server/auth")

108

});

109

}

110

}

111

});

112

113

// Async module setup

114

export default defineNuxtModule({

115

meta: {

116

name: "async-module"

117

},

118

async setup(options, nuxt) {

119

// Async operations

120

const packageInfo = await readPackageJSON();

121

122

// Add runtime config

123

updateRuntimeConfig({

124

myModule: {

125

version: packageInfo.version

126

}

127

});

128

}

129

});

130

```

131

132

### Context Management

133

134

Access and manage the Nuxt context within modules and utilities.

135

136

```typescript { .api }

137

/**

138

* Get the current Nuxt instance

139

* @returns Current Nuxt instance

140

* @throws Error if called outside Nuxt context

141

*/

142

function useNuxt(): Nuxt;

143

144

/**

145

* Try to get the current Nuxt instance

146

* @returns Current Nuxt instance or null if not available

147

*/

148

function tryUseNuxt(): Nuxt | null;

149

150

/**

151

* Get the current Nuxt context

152

* @returns Nuxt context

153

*/

154

function getNuxtCtx(): NuxtContext;

155

156

/**

157

* Run a function within Nuxt context

158

* @param nuxt - Nuxt instance

159

* @param fn - Function to run

160

* @returns Result of the function

161

*/

162

function runWithNuxtContext<T>(nuxt: Nuxt, fn: () => T): T;

163

164

interface Nuxt {

165

/** Nuxt options */

166

options: NuxtOptions;

167

/** Hook system */

168

hooks: Hookable<NuxtHooks>;

169

/** Module container */

170

moduleContainer: ModuleContainer;

171

/** Call hook */

172

callHook: (name: keyof NuxtHooks, ...args: any[]) => Promise<void>;

173

/** Add hook */

174

hook: (name: keyof NuxtHooks, fn: Function) => void;

175

/** Close Nuxt */

176

close: () => Promise<void>;

177

[key: string]: any;

178

}

179

```

180

181

**Usage Examples:**

182

183

```typescript

184

// Using Nuxt context in utilities

185

function addCustomPlugin() {

186

const nuxt = useNuxt();

187

188

addPlugin({

189

src: createResolver(import.meta.url).resolve("./plugin.js"),

190

mode: "client"

191

});

192

}

193

194

// Safe context access

195

function maybeAddPlugin() {

196

const nuxt = tryUseNuxt();

197

198

if (nuxt) {

199

addPlugin("./plugin.js");

200

}

201

}

202

203

// Running with context

204

async function setupModule(nuxt: Nuxt) {

205

await runWithNuxtContext(nuxt, () => {

206

addPlugin("./plugin.js");

207

addComponent({

208

name: "MyComponent",

209

filePath: "./components/MyComponent.vue"

210

});

211

});

212

}

213

214

// Hook management

215

function registerHooks() {

216

const nuxt = useNuxt();

217

218

nuxt.hook("ready", async () => {

219

console.log("Nuxt is ready!");

220

});

221

222

nuxt.hook("build:before", () => {

223

console.log("Build starting...");

224

});

225

}

226

```

227

228

### Plugin Management

229

230

Add and manage Nuxt plugins programmatically.

231

232

```typescript { .api }

233

/**

234

* Add a plugin to the Nuxt application

235

* @param plugin - Plugin options or path

236

*/

237

function addPlugin(plugin: AddPluginOptions | string): void;

238

239

/**

240

* Add a plugin template with processing

241

* @param pluginOptions - Plugin template options

242

* @returns Added template

243

*/

244

function addPluginTemplate(pluginOptions: NuxtPluginTemplate): NuxtTemplate;

245

246

/**

247

* Normalize plugin options

248

* @param plugin - Plugin to normalize

249

* @returns Normalized plugin

250

*/

251

function normalizePlugin(plugin: NuxtPlugin): NuxtPlugin;

252

253

interface AddPluginOptions {

254

/** Plugin source path */

255

src: string;

256

/** Plugin filename */

257

fileName?: string;

258

/** Plugin mode */

259

mode?: "client" | "server" | "all";

260

/** Plugin options */

261

options?: Record<string, any>;

262

}

263

264

interface NuxtPluginTemplate {

265

/** Template source */

266

src?: string;

267

/** Template filename */

268

filename?: string;

269

/** Template destination */

270

dst?: string;

271

/** Template options */

272

options?: Record<string, any>;

273

/** Template mode */

274

mode?: "client" | "server" | "all";

275

/** Whether plugin should be SSR-friendly */

276

ssr?: boolean;

277

}

278

```

279

280

**Usage Examples:**

281

282

```typescript

283

// Add simple plugin

284

addPlugin("~/plugins/my-plugin.client.js");

285

286

// Add plugin with options

287

addPlugin({

288

src: createResolver(import.meta.url).resolve("./runtime/plugin.js"),

289

mode: "client",

290

options: {

291

apiKey: "abc123"

292

}

293

});

294

295

// Add plugin template

296

addPluginTemplate({

297

src: createResolver(import.meta.url).resolve("./templates/plugin.ejs"),

298

filename: "my-plugin.js",

299

options: {

300

config: moduleOptions

301

}

302

});

303

304

// Add multiple plugins

305

const resolver = createResolver(import.meta.url);

306

307

addPlugin(resolver.resolve("./runtime/composables"));

308

addPlugin({

309

src: resolver.resolve("./runtime/auth.client.js"),

310

mode: "client"

311

});

312

addPlugin({

313

src: resolver.resolve("./runtime/server.server.js"),

314

mode: "server"

315

});

316

```

317

318

### Component Management

319

320

Register and manage components automatically.

321

322

```typescript { .api }

323

/**

324

* Add a component to auto-discovery

325

* @param options - Component registration options

326

*/

327

function addComponent(options: AddComponentOptions): void;

328

329

/**

330

* Add component exports for tree-shaking

331

* @param exports - Component exports to add

332

*/

333

function addComponentExports(exports: ComponentExport[]): void;

334

335

/**

336

* Add a directory for component auto-discovery

337

* @param dir - Directory options

338

*/

339

function addComponentsDir(dir: ComponentsDir): void;

340

341

interface AddComponentOptions {

342

/** Component name */

343

name: string;

344

/** Component file path */

345

filePath: string;

346

/** Export name (for named exports) */

347

export?: string;

348

/** Global registration */

349

global?: boolean;

350

/** Component prefix */

351

prefix?: string;

352

/** Component suffix */

353

suffix?: string;

354

/** Pascal case name */

355

pascalName?: string;

356

/** Kebab case name */

357

kebabName?: string;

358

/** Short name */

359

shortPath?: string;

360

/** Chunk name */

361

chunkName?: string;

362

/** Component mode */

363

mode?: "client" | "server" | "all";

364

/** Island component */

365

island?: boolean;

366

}

367

368

interface ComponentExport {

369

/** Export name */

370

name: string;

371

/** Export source */

372

as?: string;

373

/** Export from */

374

from: string;

375

}

376

377

interface ComponentsDir {

378

/** Directory path */

379

path: string;

380

/** Directory prefix */

381

prefix?: string;

382

/** Directory suffix */

383

suffix?: string;

384

/** Global components */

385

global?: boolean;

386

/** Watch directory */

387

watch?: boolean;

388

/** File extensions */

389

extensions?: string[];

390

/** File patterns */

391

pattern?: string | string[];

392

/** Ignore patterns */

393

ignore?: string[];

394

/** Transpile components */

395

transpile?: boolean;

396

/** Island components */

397

island?: boolean;

398

}

399

```

400

401

**Usage Examples:**

402

403

```typescript

404

// Add single component

405

addComponent({

406

name: "MyButton",

407

filePath: createResolver(import.meta.url).resolve("./runtime/components/MyButton.vue"),

408

global: true

409

});

410

411

// Add component with custom configuration

412

addComponent({

413

name: "LazyChart",

414

filePath: "./components/Chart.vue",

415

mode: "client",

416

prefix: "Lazy",

417

island: true

418

});

419

420

// Add components directory

421

addComponentsDir({

422

path: createResolver(import.meta.url).resolve("./runtime/components"),

423

prefix: "My",

424

global: true

425

});

426

427

// Add component exports for tree-shaking

428

addComponentExports([

429

{ name: "MyButton", from: "./components/MyButton" },

430

{ name: "MyInput", from: "./components/MyInput" },

431

{ name: "default", as: "MyCard", from: "./components/MyCard" }

432

]);

433

434

// Conditional component registration

435

if (moduleOptions.includeUI) {

436

addComponentsDir({

437

path: resolver.resolve("./runtime/ui"),

438

prefix: "UI"

439

});

440

}

441

```

442

443

### Build System Integration

444

445

Integrate with Nuxt's build system using Vite, webpack, and other build tools.

446

447

```typescript { .api }

448

/**

449

* Add a build plugin

450

* @param plugin - Build plugin to add

451

*/

452

function addBuildPlugin(plugin: any): void;

453

454

/**

455

* Add a Vite plugin

456

* @param plugin - Vite plugin to add

457

*/

458

function addVitePlugin(plugin: any): void;

459

460

/**

461

* Add a webpack plugin

462

* @param plugin - Webpack plugin to add

463

*/

464

function addWebpackPlugin(plugin: any): void;

465

466

/**

467

* Extend Vite configuration

468

* @param config - Vite config to merge

469

* @param options - Extension options

470

*/

471

function extendViteConfig(config: any, options?: ExtendConfigOptions): void;

472

473

/**

474

* Extend webpack configuration

475

* @param config - Webpack config to merge

476

* @param options - Extension options

477

*/

478

function extendWebpackConfig(config: any, options?: ExtendConfigOptions): void;

479

480

interface ExtendConfigOptions {

481

/** Development mode only */

482

dev?: boolean;

483

/** Production mode only */

484

build?: boolean;

485

/** Server-side only */

486

server?: boolean;

487

/** Client-side only */

488

client?: boolean;

489

}

490

```

491

492

**Usage Examples:**

493

494

```typescript

495

// Add Vite plugin

496

import { defineNuxtModule } from '@nuxt/kit';

497

import MyVitePlugin from 'my-vite-plugin';

498

499

export default defineNuxtModule({

500

setup() {

501

addVitePlugin(MyVitePlugin({

502

option1: 'value1'

503

}));

504

}

505

});

506

507

// Extend Vite config

508

extendViteConfig({

509

define: {

510

__MODULE_VERSION__: JSON.stringify(moduleVersion)

511

},

512

optimizeDeps: {

513

include: ['my-dependency']

514

}

515

});

516

517

// Add webpack plugin

518

import MyWebpackPlugin from 'my-webpack-plugin';

519

520

addWebpackPlugin(new MyWebpackPlugin({

521

option1: 'value1'

522

}));

523

524

// Conditional build configuration

525

extendViteConfig({

526

build: {

527

rollupOptions: {

528

external: ['external-lib']

529

}

530

}

531

}, { build: true }); // Only in production

532

533

// Add CSS processing

534

extendViteConfig({

535

css: {

536

preprocessorOptions: {

537

scss: {

538

additionalData: `@import "~/assets/styles/variables.scss";`

539

}

540

}

541

}

542

});

543

```

544

545

### Server Integration

546

547

Add server handlers, middleware, and API routes.

548

549

```typescript { .api }

550

/**

551

* Add a server handler

552

* @param handler - Server handler options

553

*/

554

function addServerHandler(handler: {

555

route?: string;

556

handler: string;

557

method?: string;

558

middleware?: boolean;

559

}): void;

560

561

/**

562

* Add development server handler

563

* @param handler - Development server handler options

564

*/

565

function addDevServerHandler(handler: {

566

route?: string;

567

handler: string;

568

method?: string;

569

}): void;

570

571

/**

572

* Add server imports

573

* @param imports - Server imports to add

574

*/

575

function addServerImports(imports: Import[]): void;

576

577

/**

578

* Add server imports directory

579

* @param dirs - Directory paths or options

580

*/

581

function addServerImportsDir(dirs: string | string[]): void;

582

583

/**

584

* Access Nitro instance

585

* @returns Nitro instance

586

*/

587

function useNitro(): Nitro;

588

```

589

590

**Usage Examples:**

591

592

```typescript

593

// Add API route

594

addServerHandler({

595

route: "/api/my-module/**",

596

handler: createResolver(import.meta.url).resolve("./server/api/handler.js")

597

});

598

599

// Add middleware

600

addServerHandler({

601

handler: createResolver(import.meta.url).resolve("./server/middleware/auth.js"),

602

middleware: true

603

});

604

605

// Add development-only handler

606

addDevServerHandler({

607

route: "/api/dev/**",

608

handler: createResolver(import.meta.url).resolve("./server/dev-handler.js")

609

});

610

611

// Add server utils

612

addServerImportsDir(createResolver(import.meta.url).resolve("./server/utils"));

613

614

// Add specific server imports

615

addServerImports([

616

{ name: "myServerUtil", from: createResolver(import.meta.url).resolve("./server/utils") }

617

]);

618

619

// Access Nitro for advanced configuration

620

const nitro = useNitro();

621

nitro.options.runtimeConfig.myModule = moduleOptions;

622

```

623

624

### Module Utilities

625

626

Additional utilities for module development.

627

628

```typescript { .api }

629

/**

630

* Create a path resolver for the module

631

* @param base - Base path (usually import.meta.url)

632

* @returns Resolver functions

633

*/

634

function createResolver(base: string | URL): Resolver;

635

636

/**

637

* Update runtime configuration

638

* @param config - Configuration to merge

639

*/

640

function updateRuntimeConfig(config: Record<string, any>): void;

641

642

/**

643

* Add template

644

* @param template - Template options

645

* @returns Added template

646

*/

647

function addTemplate(template: NuxtTemplate): NuxtTemplate;

648

649

/**

650

* Add type template

651

* @param template - Type template options

652

* @returns Added template

653

*/

654

function addTypeTemplate(template: NuxtTemplate): NuxtTemplate;

655

656

interface Resolver {

657

resolve(...paths: string[]): string;

658

resolvePath(path: string): Promise<string>;

659

}

660

```

661

662

**Usage Examples:**

663

664

```typescript

665

// Module with resolver

666

export default defineNuxtModule({

667

setup() {

668

const resolver = createResolver(import.meta.url);

669

670

// Resolve paths relative to module

671

addPlugin(resolver.resolve("./runtime/plugin.js"));

672

addComponent({

673

name: "MyComponent",

674

filePath: resolver.resolve("./runtime/components/MyComponent.vue")

675

});

676

}

677

});

678

679

// Update runtime config

680

updateRuntimeConfig({

681

myModule: {

682

apiUrl: moduleOptions.apiUrl,

683

version: "1.0.0"

684

}

685

});

686

687

// Add templates

688

addTemplate({

689

filename: "my-module-config.mjs",

690

src: resolver.resolve("./templates/config.ejs"),

691

options: {

692

...moduleOptions

693

}

694

});

695

696

// Add TypeScript definitions

697

addTypeTemplate({

698

filename: "types/my-module.d.ts",

699

src: resolver.resolve("./templates/types.d.ts"),

700

options: moduleOptions

701

});

702

```

703

704

## Complete Module Example

705

706

```typescript

707

import { defineNuxtModule, createResolver, addPlugin, addComponent, addServerHandler, updateRuntimeConfig } from '@nuxt/kit';

708

709

interface ModuleOptions {

710

apiUrl: string;

711

features: {

712

auth: boolean;

713

analytics: boolean;

714

};

715

}

716

717

export default defineNuxtModule<ModuleOptions>({

718

meta: {

719

name: "awesome-module",

720

version: "1.0.0",

721

configKey: "awesomeModule",

722

compatibility: {

723

nuxt: "^3.0.0"

724

}

725

},

726

defaults: {

727

apiUrl: "/api",

728

features: {

729

auth: true,

730

analytics: false

731

}

732

},

733

async setup(options, nuxt) {

734

const resolver = createResolver(import.meta.url);

735

736

// Add runtime config

737

updateRuntimeConfig({

738

awesomeModule: {

739

apiUrl: options.apiUrl

740

}

741

});

742

743

// Add main plugin

744

addPlugin({

745

src: resolver.resolve("./runtime/plugin.js"),

746

options

747

});

748

749

// Add components

750

addComponent({

751

name: "AwesomeButton",

752

filePath: resolver.resolve("./runtime/components/AwesomeButton.vue"),

753

global: true

754

});

755

756

// Conditional features

757

if (options.features.auth) {

758

addServerHandler({

759

route: "/api/auth/**",

760

handler: resolver.resolve("./server/auth.js")

761

});

762

763

addPlugin({

764

src: resolver.resolve("./runtime/auth.client.js"),

765

mode: "client"

766

});

767

}

768

769

if (options.features.analytics) {

770

addPlugin({

771

src: resolver.resolve("./runtime/analytics.js"),

772

options: {

773

trackingId: options.trackingId

774

}

775

});

776

}

777

778

// Development utilities

779

if (nuxt.options.dev) {

780

addDevServerHandler({

781

route: "/api/awesome-dev/**",

782

handler: resolver.resolve("./server/dev.js")

783

});

784

}

785

786

console.log(`✨ Awesome Module initialized with API URL: ${options.apiUrl}`);

787

}

788

});

789

```

790

791

## Types

792

793

```typescript { .api }

794

interface NuxtCompatibility {

795

nuxt?: string;

796

bridge?: boolean;

797

}

798

799

interface ModuleContainer {

800

addModule(module: any, options?: any): Promise<void>;

801

requireModule(module: any, options?: any): Promise<any>;

802

addPlugin(template: any): void;

803

addLayout(template: any, name?: string): void;

804

addServerMiddleware(middleware: any): void;

805

extendBuild(fn: Function): void;

806

extendRoutes(fn: Function): void;

807

}

808

809

interface NuxtContext {

810

nuxt: Nuxt;

811

isStatic: boolean;

812

isDev: boolean;

813

isHMR: boolean;

814

app: any;

815

payload: any;

816

}

817

818

interface Import {

819

name: string;

820

as?: string;

821

from: string;

822

}

823

824

interface Nitro {

825

options: NitroOptions;

826

hooks: Hookable;

827

[key: string]: any;

828

}

829

830

interface NitroOptions {

831

runtimeConfig: Record<string, any>;

832

[key: string]: any;

833

}

834

```