This file provides guidance to WARP (warp.dev) when working with code in this repository.
This is a Declarative Shadow DOM (DSD) with Preact project that demonstrates modern web component architecture using Deno as the runtime. It showcases reusable components with encapsulation, server-side rendering (SSR), and dual packaging for both Deno and npm ecosystems.
deno task dev- Start development server with hot reload (serves on http://localhost:8000)deno task serve- Start production server without file watchingdeno task build- Build and package for npm distribution (outputs topackage/directory)deno task ssg- Generate static site HTML files
The build process (deno task build) performs multiple steps:
- Uses
@deno/dntto transpile Deno TypeScript to Node.js compatible code - Generates static HTML using SSG (Static Site Generation)
- Copies CSS templates to the package directory
- Runs Vite build for optimized bundling
- Uses JSPM to generate optimized import maps with integrity and preloading
The project implements components using two complementary approaches:
-
Custom Elements (
elements/directory):- Native Web Components with Shadow DOM
- TypeScript classes extending
HTMLElement - Examples:
Button,Counter,ButtonPreact,CounterPreact
-
Preact Components (
components/directory):- Standard Preact functional components
- Server-side renderable
- Examples:
Button,Counter,DSDButton,DSDCounter
main.tsxserves as the primary server entry point using Deno's native HTTP server- Route-based file serving with explicit URL patterns for assets
- Full HTML document generation with
renderToStringAsyncfrom Preact - Declarative Shadow DOM templates embedded in server-rendered HTML
- Development: Uses
deno.jsonimports with path aliases (e.g.,#button,#counter) - Browser: Uses
importmap.jsonwith CDN URLs for production dependencies - Build: Transpiles and resolves all imports for npm compatibility
- Uses
@preact/signalsfor reactive state management - Shared state between components via
signals/counter.ts - Enables cross-component reactivity without prop drilling
components/- Preact components for SSR and compositionelements/- Web Components (Custom Elements) for browser hydrationtemplates/- HTML templates and CSS for Shadow DOM stylingfunctions/- Build scripts, bundling, and deployment configurationdom/- Browser-specific code that registers Custom Elementspackage/- Generated npm-compatible output (created by build process)
- Adding new components: Create both a Preact component (
components/) and a Custom Element (elements/) if browser interactivity is needed - Styling: Place CSS in
templates/directory - it gets copied to the package during build - State: Use signals from
signals/for shared reactive state - Import aliases: Use the
#prefix imports defined indeno.json(e.g.,#button,#home)
- Use
deno task devfor rapid iteration with hot reload - Visit
/elementsroute to see the component showcase - Check
package/directory after build to verify npm output
After running deno task build, verify:
package/esm/contains transpiled JavaScript modulespackage/index.htmlis generated with proper import maps- CSS files are copied to
package/templates/ - Vite and JSPM optimizations are applied
- Runtime: Deno (TypeScript-first, secure by default)
- UI Framework: Preact (lightweight React alternative)
- State Management:
@preact/signals(fine-grained reactivity) - Web Standards: Custom Elements, Shadow DOM, Declarative Shadow DOM
- Build Tools:
@deno/dnt, Vite, JSPM - Server: Native Deno HTTP server with URL pattern routing
- Deployment: Cloudflare Workers compatible (via Vite plugin)
The project uses server-rendered Shadow DOM templates that hydrate on the client. Components like DSDButton and DSDCounter render with <template shadowrootmode="open"> for immediate styling encapsulation.
Browser-side Custom Elements are registered in dom/main.ts and loaded via package/esm/dom/main.js. The server pre-renders the HTML structure while the client-side code adds interactivity.
The dual import map system allows the same component code to work in both server (Deno) and browser (CDN) environments. Path aliases in deno.json resolve to different targets during development vs. build.