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

@shadow-js/core

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shadow-js/core

ShadowJS core reactivity and DOM runtime

latest
Source
npmnpm
Version
0.1.0
Version published
Weekly downloads
5
66.67%
Maintainers
1
Weekly downloads
 
Created
Source

ShadowJS Core Framework

npm version TypeScript License: MIT

The core ShadowJS framework providing fine-grained reactivity, JSX runtime, and essential UI components.

✨ Features

  • 🎯 Fine-grained Reactivity: Only re-render what actually changes
  • ⚡ Fast Runtime: Minimal overhead with optimized DOM updates
  • 🎨 JSX-First: Familiar React-like syntax with powerful extensions
  • 📦 Tree-Shakable: Only bundle what you use
  • 🔧 TypeScript Ready: Full type safety and IntelliSense support
  • 🎭 Component System: Built-in components for common UI patterns

📦 Installation

npm install @shadow-js/core

For development with hot reload and JSX compilation:

npm install @shadow-js/core @shadow-js/vite

🚀 Quick Start

import { useStore, Show, For } from "@shadow-js/core";

function Counter() {
  const [count, setCount] = useStore(0);
  const [items, setItems] = useStore(["Shadow", "JS", "Reactivity"]);

  return (
    <div>
      <h2>Counter: {() => count()}</h2>
      <button onClick={() => setCount(count() + 1)}>Increment</button>

      <Show when={() => count() > 5} fallback={<p>Keep clicking!</p>}>
        <p>🎉 You reached {() => count()}!</p>
      </Show>

      <ul>
        <For each={() => items()}>{(item) => <li>{() => item}</li>}</For>
      </ul>
    </div>
  );
}

🎯 Core Concepts

Reactive Stores

Create reactive state that automatically updates dependent computations:

import { useStore } from "@shadow-js/core";

function App() {
  const [count, setCount] = useStore(0);
  const doubled = () => count() * 2; // Reactive computation

  return (
    <div>
      <p>Count: {() => count()}</p>
      <p>Doubled: {() => doubled()}</p> {/* Updates automatically */}
      <button onClick={() => setCount(count() + 1)}>+</button>
    </div>
  );
}

Effects and Lifecycle

import { useEffect, onMount, onCleanup } from "@shadow-js/core";

function Timer() {
  const [time, setTime] = useStore(new Date());

  onMount(() => {
    console.log("Component mounted");
  });

  useEffect(() => {
    const interval = setInterval(() => {
      setTime(new Date());
    }, 1000);

    // Cleanup on unmount or dependency change
    return () => clearInterval(interval);
  });

  onCleanup(() => {
    console.log("Component unmounting");
  });

  return <div>Current time: {() => time().toLocaleTimeString()}</div>;
}

Conditional Rendering

import { Show } from "@shadow-js/core";

function UserStatus({ user }) {
  return (
    <Show when={() => user()} fallback={<div>Please log in</div>}>
      <div>Welcome back, {() => user().name}!</div>
    </Show>
  );
}

Lists with For

import { For } from "@shadow-js/core";

function TodoList({ todos }) {
  return (
    <ul>
      <For each={() => todos()}>
        {(todo, index) => (
          <li>
            {() => index() + 1}. {() => todo.title}
          </li>
        )}
      </For>
    </ul>
  );
}

Switch/Case Pattern

import { Switch, Match } from "@shadow-js/core";

function StatusDisplay({ status }) {
  return (
    <Switch fallback={<div>Unknown status</div>}>
      <Match when={() => status() === "loading"}>
        <div>Loading...</div>
      </Match>
      <Match when={() => status() === "success"}>
        <div>Success!</div>
      </Match>
      <Match when={() => status() === "error"}>
        <div>Error occurred</div>
      </Match>
    </Switch>
  );
}

Async Operations with Suspense

import { Suspense, lazy } from "@shadow-js/core";

// Lazy load components
const LazyComponent = lazy(() => import("./HeavyComponent"));

function App() {
  return (
    <Suspense fallback={<div>Loading component...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

📚 API Reference

Reactivity Hooks

HookDescription
useStore<T>(initialValue)Create a reactive store
useEffect(fn, deps?)Run side effects when dependencies change
useMemo<T>(fn, deps?)Memoize expensive computations
useId()Generate unique IDs
onMount(fn)Run code when component mounts
onCleanup(fn)Run cleanup code when component unmounts

Control Flow Components

ComponentDescription
<Show>Conditional rendering with fallback
<For>Render lists with automatic key management
<Switch>Multiple conditional rendering
<Match>Case condition for Switch
<Suspense>Handle async operations
<ErrorBoundary>Catch and handle errors

Utilities

UtilityDescription
createContext<T>()Create a context for dependency injection
useContext<T>(context)Consume context values
lazy<T>(importFn)Lazy load components
render(component, container)Render component to DOM
FragmentGroup elements without wrapper

🔧 Advanced Usage

Custom Hooks

import { useStore, useEffect } from "@shadow-js/core";

function useLocalStorage<T>(key: string, initialValue: T) {
  const [storedValue, setStoredValue] = useStore<T>(() => {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      return initialValue;
    }
  });

  useEffect(() => {
    try {
      localStorage.setItem(key, JSON.stringify(storedValue()));
    } catch (error) {
      console.warn(`Error saving to localStorage:`, error);
    }
  });

  return [storedValue, setStoredValue] as const;
}

Context and Global State

import { createContext, useContext } from "@shadow-js/core";

const ThemeContext = createContext();

function ThemeProvider({ children }) {
  const [theme, setTheme] = useStore<"light" | "dark">("light");

  const toggleTheme = () => {
    setTheme(theme() === "light" ? "dark" : "light");
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error("useTheme must be used within ThemeProvider");
  }
  return context;
}

Error Boundaries

import { ErrorBoundary } from "@shadow-js/core";

function App() {
  return (
    <ErrorBoundary fallback={(error) => <div>Error: {error.message}</div>}>
      <ComponentThatMightError />
    </ErrorBoundary>
  );
}

🔌 Integration

Vite Plugin

For the best development experience, use the ShadowJS Vite plugin:

vite.config.ts

import { defineConfig } from "vite";
import shadow from "@shadow-js/vite";

export default defineConfig({
  plugins: [shadow()],
});

Manual JSX Setup

If you prefer manual setup, configure your bundler to use ShadowJS JSX runtime:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "@shadow-js/core"
  }
}

🎨 Styling

ShadowJS works with any CSS solution:

// Inline styles (reactive)
<div style={() => ({ color: theme() === "dark" ? "white" : "black" })}>
  Dynamic styling
</div>

// CSS Classes
<div className="my-component">
  Static styling
</div>

// CSS Modules
import styles from "./Component.module.css";
<div className={styles.container}>CSS Modules</div>

🏗️ Architecture

ShadowJS is built with performance and developer experience in mind:

Fine-grained Reactivity System

  • Automatic dependency tracking: No manual dependency arrays
  • Efficient updates: Only affected components re-render
  • Memory management: Automatic cleanup of unused subscriptions

Optimized Runtime

  • Minimal bundle size: Core runtime is < 9KB gzipped
  • Fast reconciliation: Optimized DOM diffing algorithm
  • Memory efficient: Smart memory management and cleanup

Developer Experience

  • TypeScript first: Full type safety and IntelliSense
  • Great error messages: Clear error reporting and debugging
  • Hot reload friendly: Optimized for development workflows

📚 Examples

Check out the examples documentation for comprehensive code examples covering:

  • Basic patterns and best practices
  • Advanced reactive patterns
  • Real-world application examples
  • Integration patterns

🤝 Contributing

We welcome contributions! See the Contributing Guide for details.

📄 License

MIT License - see LICENSE for details.

📞 Support

Built by Jehaad AL-Johani for fine-grained reactivity.

Keywords

shadowjs

FAQs

Package last updated on 22 Aug 2025

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