🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@ecopages/core

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ecopages/core

Core package for Ecopages

Source
npmnpm
Version
0.2.0-beta.4
Version published
Maintainers
1
Created
Source

@ecopages/core

The foundational engine for the Ecopages framework. It provides the core build pipeline, development server, routing, and plugin architecture required to run an Ecopages application.

Overview

Ecopages is an extensible static site generator (SSG) built around a Bun-first core with Node fallback support and Vite-hosted compatibility for advanced dev and build orchestration. It embraces a strictly MPA (Multi-Page Application) architecture by default, rendering HTML at build-time or request-time, and hydrating interactive islands only where necessary.

  • Runtime Boundary: createApp() prefers Bun when available and falls back to Node otherwise. Vite and Nitro still own host-side dev and build orchestration.
  • Build Ownership: Bun-native execution keeps a core-owned build path. Vite and Nitro own host-side transforms, module graph behavior, and deployment-oriented builds.
  • Framework agnostic: First-class support for KitaJS, Lit, React, and MDX via official integration plugins.
  • Extensible: Hook into the build process with custom processors or rendering integrations.

Current Architecture

The current core package is organized around app-owned runtime state and explicit service boundaries.

The important ownership rules are:

  • ConfigBuilder.build() finalizes app-owned build and runtime services.
  • browser bundling and server module loading are explicit, separate paths.
  • runtime hosts stay thin and delegate framework work into core services.
  • HMR and invalidation use shared graph-aware services instead of runtime-specific ad hoc wiring.

Bootstrap And Runtime Ownership

flowchart TD
	A[eco.config.ts] --> B[ConfigBuilder.build]
	B --> C[App build adapter]
	B --> D[App build manifest]
	B --> E[Build executor]
	B --> F[Dev graph service]
	B --> G[Host module loader boundary]
	G --> H[PageModuleImportService]
	E --> H
	E --> I
	E --> I[BrowserBundleService]
	H --> J[Runtime app adapter]
	J --> K[Bun adapter or Node adapter]
	D --> I

Development Invalidation And HMR Flow

flowchart TD
	A[File change] --> B[ProjectWatcher]
	B --> C[DevelopmentInvalidationService]
	C --> D{Change kind}
	D -->|Route or server source| E[Invalidate server modules]
	D -->|Public or include| F[Reload browser]
	D -->|Processor-owned asset| G[Notify processor only]
	D -->|HMR-eligible source| H[Core HMR manager]
	H --> I[Strategy selection]
	I --> J[Core JsHmrStrategy]
	I --> K[Integration strategy e.g. ReactHmrStrategy]
	J --> L[BrowserBundleService]
	K --> L
	K --> M[importServerModule]
	M --> N[ServerModuleTranspiler]
	L --> O[Updated browser bundle]
	O --> P[Client bridge broadcast]

The manager/orchestration layer is core-owned, but framework-specific strategies such as React HMR are contributed by integrations and registered with the shared HMR manager.

Practical Summary

  • ConfigBuilder seeds one app-owned build ownership path, adapter, manifest, executor, dev graph, and runtime registry.
  • BrowserBundleService is the shared browser build seam used by HMR and asset-oriented browser output paths.
  • ServerModuleTranspiler is the shared server-side source loading seam used by runtime bootstrap and HMR metadata loading.
  • createApp() stays the universal runtime entrypoint, while Vite and Nitro hosts own their advanced dev and build workflows.
  • One bundled adapter is the default bundler. Vite-based apps route through the ViteHostBuildAdapter boundary marker instead.

Documentation Map

Use this package README as the top-level map, then drill into the focused subsystem READMEs:

  • src/config/README.md: config finalization and app-owned runtime/build state
  • src/plugins/README.md: integration and processor authoring contracts
  • src/build/README.md: build adapter, executor, and development build coordination
  • src/services/README.md: cross-cutting runtime services and orchestration helpers
  • src/adapters/README.md: Bun, Node, and shared adapter boundaries
  • src/hmr/README.md: HMR strategy and update-layer ownership
  • src/router/README.md: route discovery, matching, and browser navigation coordination
  • src/route-renderer/README.md: rendering orchestration and dependency resolution
  • src/static-site-generator/README.md: static build execution path
  • src/eco/README.md: eco authoring APIs for pages, layouts, and components

The intended reading order is:

  • this file for the big-picture architecture
  • src/config/README.md for config and lifecycle ownership
  • src/plugins/README.md and src/build/README.md for contribution contracts
  • src/services/README.md and src/adapters/README.md for runtime execution
  • src/router/README.md and src/route-renderer/README.md for request-time flow

Installation

bun add @ecopages/core

(You can also use npm, yarn, or pnpm)

Basic Usage

The Ecopages architecture revolves around an eco.config.ts file and an application entry point.

1. Configuration (eco.config.ts)

Configure your integratons, processors, and default metadata. Ecopages uses a builder pattern:

import { ConfigBuilder } from '@ecopages/core/config-builder';
// import your desired plugins...

const config = await new ConfigBuilder()
	.setRootDir(import.meta.dirname)
	.setBaseUrl(import.meta.env.ECOPAGES_BASE_URL ?? 'http://localhost:3000')
	.setDefaultMetadata({
		title: 'My Ecopages Site',
		description: 'Built with Ecopages',
	})
	// .setIntegrations([kitajsPlugin()])
	.build();

export default config;

2. Application Entry (app.ts)

Start the application using createApp. It will choose the Bun adapter when Bun is available and fall back to Node otherwise.

import { createApp } from '@ecopages/core/create-app';
import appConfig from './eco.config';

const app = await createApp({ appConfig });

await app.start();

3. Creating Pages

Use the eco.page() factory to define static routes. Place these in src/pages/:

import { eco } from '@ecopages/core';
import { BaseLayout } from '@/layouts/base-layout';

export default eco.page({
	layout: BaseLayout,
	metadata: () => ({
		title: 'Home',
	}),
	render: () => (
		<div>
			<h1>Welcome to Ecopages</h1>
		</div>
	),
});

4. Reusable Components

Define components with eco.component() to automatically inject necessary stylesheets or scripts only when that component is rendered:

import { eco } from '@ecopages/core';

export const MyButton = eco.component({
	dependencies: {
		stylesheets: ['./button.css'],
	},
	render: ({ label }) => <button className="my-button">{label}</button>,
});

Dependency ownership affects final asset packaging:

  • Stylesheets and scripts declared from eco.html() stay Html-owned and can be emitted as shared app-wide assets.
  • Stylesheets and scripts declared from Pages, Layouts, or Components are resolved into page-owned assets for the rendered route.
  • This split is intentional. Shared Html assets can be cached across routes, while page-owned assets can change without invalidating the global shell.

5. API Handlers

Add server-side routes using defineApiHandler. Register them on your app instance before starting:

import { defineApiHandler } from '@ecopages/core';

export const helloWorld = defineApiHandler({
	path: '/api/hello',
	method: 'GET',
	handler: async ({ response }) => {
		return response.json({ message: 'Hello World' });
	},
});

Attach the handler in your app.ts entry:

// app.ts
import { createApp } from '@ecopages/core/create-app';
import { helloWorld } from './handlers/hello';
import appConfig from './eco.config';

const app = await createApp({ appConfig });

app.get(helloWorld); // Register the API handler

await app.start();

See the official documentation for advanced usage, API handlers, and integrations.

Import Structure

Use the create-app subpath for runtime startup and the root package for standard authoring helpers:

import { createApp } from '@ecopages/core/create-app';
import { defineApiHandler, defineGroupHandler, eco } from '@ecopages/core';

[!NOTE] createApp is the recommended entrypoint over EcopagesApp.

Runtime Escape Hatches

Use runtime-specific subpaths only when you explicitly need Bun-native APIs that bypass the universal abstractions:

  • @ecopages/core/bun

Entry Point Roles

The published subpaths are grouped by architectural role rather than by source folder.

App Authoring

Use these entrypoints when building an Ecopages app:

  • @ecopages/core
  • @ecopages/core/create-app
  • @ecopages/core/config-builder
  • @ecopages/core/errors
  • @ecopages/core/html
  • @ecopages/core/hash
  • @ecopages/core/declarations
  • @ecopages/core/env
  • @ecopages/core/bun

Browser Navigation

Use these entrypoints when a browser runtime needs to coordinate document ownership and link intent:

  • @ecopages/core/router/navigation-coordinator
  • @ecopages/core/router/link-intent

Extension Authoring

Use these entrypoints when implementing integrations, processors, or source transforms:

  • @ecopages/core/plugins/integration-plugin
  • @ecopages/core/plugins/processor
  • @ecopages/core/plugins/source-transform
  • @ecopages/core/route-renderer/integration-renderer
  • @ecopages/core/services/asset-processing-service
  • @ecopages/core/hmr/hmr-strategy
  • @ecopages/core/integrations/ghtml

Host And Runtime Composition

Use these entrypoints only when implementing host adapters or framework-owned bundling seams:

  • @ecopages/core/dev/host-runtime
  • @ecopages/core/build/build-adapter
  • @ecopages/core/build/build-types
  • @ecopages/core/plugins/foreign-jsx-override-plugin

These host-facing entrypoints are narrower compatibility seams. App code and most extensions should prefer the app-authoring or extension-authoring surfaces.

Keywords

ecopages

FAQs

Package last updated on 15 Jun 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts