Opensource by Reddit – Telegram
Opensource by Reddit
20 subscribers
5 photos
2 videos
9.56K links
Reddit's ♨️ take on Open Source Technology.

Join the discussion ➡️ @opensource_chats

Channel Inquiries ➡️ @group_contacts_bot

👄 TIPS ➡️➡️➡️ https://news.1rj.ru/str/addlist/mB9fRZOHTUk5ZjZk

🌈 made possible by
@reddit2telegram
@r_channels
Download Telegram
A definitive list of open source

https://github.com/mustbeperfect/definitive-opensource

I built this list is to consolidate the "best" open source projects in a scalable manner - and by best I mean well-maintained and relatively popular. The problem I found with most other lists is that they included many abandoned projects, partly because of the smaller projects they also included. As someone who was trying to replace everything proprietary with open source, this clutter really frustrated me.

Don't get me wrong, I have nothing against small projects, but I wanted a list of projects that had momentum behind them and weren't just some selfhosted web app someone made in a day, even if technically, it had a completed feature set.

I've tried to accomplish this by automating all of the tedious parts of maintaining a list. Python noscripts generate the README, and maintenance noscripts checks for formatting errors in the JSON files, update stats from the Github api, and also check whether projects are potentially abandoned based on last commit date or if they were archived.

These results are outputted to md files with humans having the final say for whether projects are added or removed.

I'm very happy with where this last has gotten as I feel it's very comprehensive now. Feedback and contributions are appreciated as this list is, in itself, open source!

https://redd.it/1olt000
@r_opensource
LyteNyte Grid, our open source React data grid, now plays nice with Shadcn/UI + Tailwind

Hey everyone, 

The team at 1771 Technologies has been working up something great for the shadcn/ui and React communities. We're excited to share that LyteNyte Grid, our high-performance React data grid, is now available directly via the shadcn/ui registry.  

# Fast shadcn/ui Setup, Simple Integration

LyteNyte Grid is a headless (or pre-styled) React data grid compatible with Tailwind. It’s designed for flexibility and massive scale. We've added native themes for shadcn/ui (both light and dark), using shadcn/ui's own Tailwind token system. For developers, that means:

No extra styling layers to manage.
If you update your theme tokens, the grid updates automatically.
It looks and feels like a natural extension of your shadcn/ui app.

You can install it using the standard shadcn/ui command and get up and running in minutes. Check out our [installation with shadcn guide](
https://www.1771technologies.com/docs/intro-installation-shadcn) for more details or simply run:

npx shadcn@latest add
@lytenyte/lytenyte-core

# Built For All LyteNyte Grid Users

The new Shadcn themes are part of our open-source Core edition, which, at only 36kb (gzipped), already offers powerful features for free, such as:

Row grouping
Master-detail rows
Data aggregation

So, if you're building dashboards, admin panels, or internal tools and want them to feel native to shadcn/ui, LyteNyte Grid takes care of the heavy lifting so you can focus on features, not plumbing.

# And Shoutout…

Big thank you to everyone in the React and web development community who has supported our project so far. Our roadmap is stacked with new features we are working on implementing. Your support has meant everything to us. As always, we are keen to hear your feedback.

If you're interested in LyteNyte Grid, check out our demo. Or, if you prefer a deeper technical look, all our code is available on GitHub. Feel free to drop us a star, suggest improvements, or share your thoughts.

# TDLR

LyteNyte Grid is now available via the shadcn/ui registry. We’ve built two new shadcn/ui themes (Light and Dark), that you can set up and begin using in minutes.

https://redd.it/1olzckg
@r_opensource
I built Solveig, it turns any LLM into an assistant in your terminal. Think Claude Code with trust issues

## Solveig

Solveig is an agentic runtime that runs as an assistant in your terminal

It that can plan tasks, read files, edit your code, run commands and more

### Watch 45s demo

---

## Quick Start

### Installation

# Core installation (OpenAI + local models)
pip install solveig

# With support for Claude and Gemini APIs
pip install solveigall

### Running

# Run with a local model
solveig -u "http://localhost:5001/v1" "Create a demo BlackSheep webapp"

# Run from a remote API like OpenRouter
solveig -u "https://openrouter.ai/api/v1" -k "<APIKEY>" -m "gpt-5"

See [Usage](
https://github.com/FSilveiraa/solveig/blob/main/docs/usage.md) for more.

---

## Features

🤖 **AI Terminal Assistant** - Automate file management, code analysis, project setup, and system tasks using
natural language in your terminal.

🛡️ **Safe by Design** - Granular consent controls with pattern-based permissions and file operations
prioritized over shell commands.

🔌 **Plugin Architecture** - Extend capabilities through drop-in Python plugins. Add SQL queries, web scraping,
or custom workflows with 100 lines of Python.

📋 **Modern CLI** - Clear interface with task planning and listing, file content previews, diff editing,
API usage tracking, code linting, waiting animations and rich tree displays for informed user decisions.

🌐 **Provider Independence** - Works with OpenAI, Claude, Gemini, local models, or any OpenAI-compatible API.

**tl;dr: it tries to be similar to [Claude Code](
https://claude.com/product/claude-code), [Kolosal-CLI](https://github.com/KolosalAI/kolosal-cli) or [Aider](https://aider.chat/)
while including explicit guardrails, a consent model grounded on a clear interface, deep configuration, an easy plugin system, and able to integrate any model, backend or API.**

See the [Features](
https://github.com/FSilveiraa/solveig/blob/main/docs/about.md#features-and-principles) for more.

---

## Typical tasks

- "Find and list all the duplicate files anywhere inside my ~/Documents/"
- "Check my essay Final.docx for spelling, syntax or factual errors while maintaining the tone"
- "Refactor my test
database.ts suite to be more concise"
- "Try and find out why my computer is slow"
- "Create a dockerized BlackSheep webapp with a test suite, then build the image and run it locally"
- "Review the documentation for my project and confirm the config matches the defaults"

---

### So it's yet another LLM-in-my-terminal?

Yes, and there's a detailed Market Comparison
to similar tools in the docs.

The summary is that I think Solveig has a unique feature set that fills a genuine gap.
It's a useful tool built on clear information display, user consent and extensibility.
It's not an IDE extension nor does it require a GUI, and it both tries to do small unique things that no competitor
really has, and to excel at features they all share.

At the same time, Solveig's competitors are much more mature projects with real user testing, and you should
absolutely try them out. A lot of my features where anywhere from influenced to functionally copied from other
existing tools - at the end of the day, the goal of tech, especially open-source software, is to make people's
lives easier.

### Upcoming

I have a Roadmap available,
feel free to suggest new features or improvements. Currently, I'm trying to implement some form of user-defined
system prompt and find a way to get token counting from API messages instead of relying on encoders.
A cool aspect of this project is that, with some focus on dev features like code linting and diff view, I can use Solveig to work on Solveig itself.

I appreciate any feedback or comment, even if it's just confusion - if you can't see how Solveig
Building a Local Voice Dictation app

I discovered Wispr Flow a while back, and it’s honestly been a game changer for how I vibe code or just interact with AI in general. That said, there are a few fundamental drawbacks that bugged me over time:

All your audio is sent to the cloud
It’s $12/month. Why does everything have to be a subnoscription these days?

I've scoured through for some more options but none is truly free and open source with a Wispr Flow feel. So I built Transcrybe, a FOSS push to dictate tool. (currently only for MacOS)


Here are a couple of key selling points:

Free and Open Source
Choose your own model (currently Whisper Tiny, Base, or Small)
Instant dictation, under 1 second, even for long sentences
Privacy-first — no data uploads, and all recordings are deleted after dictation

Sure, it won't format or catch obscure phrases as perfectly as a cloud based tool like Wispr Flow. But in my testing, it's basically just as good for most use cases.


Check it out here: https://github.com/spacefarers/Transcrybe

This seems like a relatively simple idea so if someone know of another cool project like this I'd be happy to instead contribute to that one as well.

Let me know what you think!

https://redd.it/1om2188
@r_opensource
PAL v1.2 released - now with support for character events, attaching and detaching foreign windows

Hey everyone,

PAL (Prime Abstraction Layer) — a thin, explicit, low-overhead abstraction over native OS APIs and graphics APIs. Originally named as Platform Abstraction Layer, PAL has evolved into Prime Abstraction Layer — the first and most direct layer between your engine or software and the operating system.

I've just released v1.2.0 and below are the new improvements and features.

# Whats New

Added palGetInstance() to retrieve the native display or instance handle.
Added palAttachWindow() for attaching foreign windows to PAL.
Added palDetachWindow() for detaching foreign windows from PAL.
Added PAL_EVENT_KEYCHAR to PalEventType enum.
Added documentation for event bits(payload) layout.
Added multi-threaded OpenGL example: demonstrating Multi-Threaded OpenGL Rendering.
Added attaching and detach foreign windows example.
Added key character example.

see CHANGELOG.

Binaries for Windows and Linux with source code has been added in the release section.

Contributions are welcome!

https://github.com/nichcode/PAL

https://redd.it/1ombs3n
@r_opensource
So I made a Full-stack coding framework at 16 years old called ScrollForge: Causal Graph Programming which unifies state, logic, and style in one causal graph.

Hello everyone! So basically I had this idea where the frontend, backend, state, logic etc etc act as nodes within a causal graph, so I went ahead and made a framework on it! Basically it has three engines to be precise with many functions, it took me a longg time to make!

Below is a modest briefing about this framework, however, I must exclaim this is not everything, not even close. If you'd like to see everything, kindly go to the github repo and find the complete guide md to see all of its functions, there are even code snippits in that!

Also if you don't wanna go through the hassle, just go to your root directory and type

npm install scrollforge

Also, I'd love some critique on this ;D

# TL;DR

Paradigm: Causal Graph Programming (CGP) — you wire functions, not components; the framework auto-detects what each function needs and “snaps” it into a single causal graph (UI ⇄ logic ⇄ effects ⇄ style ⇄ backend).
Three engines:
ScrollMesh → component/templating via context auto-wiring (unlimited functions, zero manual wiring).
ScrollScript → universal signal store (client + server) with actions, watchers, derived signals, time travel.
ScrollWeave → logic-reactive styling (state/logic drives CSS & animations at runtime).
Why now: less boilerplate, fewer classes/hooks/providers, more causality visibility.
Showcase: real-time chat app in < 500 lines (HTML + JS + a tiny server).
Use cases: dashboards, real-time apps, design systems that react to logic, compact full-stack prototypes.
One-liner: ScrollForge – Causal Graph Programming: unify state, logic, style, and backend into one reactive graph.

# What is “Causal Graph Programming”?

The short version:
Instead of pushing data through props and bouncing events back through callbacks (typical UI frameworks), CGP lets you register as many functions as you want. Each function declares its intent implicitly by its signature (parameters), and the engine auto-provides matching contexts:

1. ({ ...stateProps }) => ui → UI renderer (gets state)
2. (events, state) => { ... } → event logic
3. (state, weave) => { ... } → styling/animation driven by state
4. (state, effects) => { ... } → reactive effects
5. () => ({ ... }) → initial state provider 
(…and several more contexts, all optional.)

Order doesn’t matter. Wiring doesn’t exist. The framework assembles a causal graph out of your functions and keeps it live.

\
*

## Why this is different?

No props drilling, no provider pyramids, no manual event buses.
UI, logic, effects, and styles coordinate through shared, reactive signals (ScrollScript) and auto-wired contexts (ScrollMesh).
Style is not static: ScrollWeave treats CSS as a live system, not a file.

\
*

# The three engines (in one project)

**

# 1) ScrollMesh — recursive component assembly (auto-wiring):

Write components by passing functions. The engine reads signatures and provides what you need.

import { HTMLScrollMesh } from 'scrollforge/dist/mesh-full.browser.js';

const Counter = HTMLScrollMesh(
// UI (gets state via destructuring)
({ count }) => <button class="btn">Count: ${count}</button>,

// Logic (gets events + state)
(events, state) => {
events.on('click', '.btn', () => state.count++);
},

// Initial state
() => ({ count: 0 })
);

Counter.mount('#app');


# 2) ScrollScript — universal data flow (signals, actions, derived):

Client and server share the same API. Signals update; watchers react; derived signals memoize computed values.

// Create global signals
app.Script.signal('messages', );
app.Script.signal('username', '');
app.Script.watch('messages', (msgs) => console.log('Count:', msgs.length));


# 3) ScrollWeave — logic-reactive styling

Let state and logic shape style at runtime.

(state, weave) => {
weave.when('.status',
state.online,
{ background: 'rgba(76, 175, 80, .2)' },
{ background: 'rgba(244, 67, 54, .2)' }
);

// Micro-interaction
weave.spring('.btn', { transform: 'scale(1.0)' }, { stiffness: 200, damping: 20 });
};


# The <500-line demo: real-time chat

Using this paradigm, we made a fully working chatapp in under 500 lines of code (present in the github repo at the end).

# ScrollMesh Context Auto-Wiring - Deep Dive

The Revolutionary Breakthrough

ScrollMesh Context is the most powerful feature in ScrollForge. It allows you to pass UNLIMITED functions that automatically detect what they need and connect themselves.

How It Works

import { HTMLScrollMesh } from 'scrollforge/mesh';

const component = HTMLScrollMesh(
function1,
function2,
function3,
// ... add as many as you want!
);


The framework:

1. Reads each function's signature (parameters)
2. Detects what contexts each function needs
3. Automatically provides those contexts
4. Wires everything together
5. NO manual configuration required!

# The 8 Available Contexts:

Every function can request any of these contexts by adding them as parameters:

1. state - Reactive State Proxy
Get it by: Adding state as parameter
What you can do:

(state) => {
// READ
const count = state.count;
const name = state.user.name;

// WRITE (triggers re-render!)
state.count++;
state.user.name = 'Jane';

// Deep updates work
state.user.profile.settings.theme = 'dark';

// Arrays
state.items.push(newItem);
state.items = ...state.items, newItem;
}


2. events - Event System
Get it by: Adding events as parameter
What you can do:

(events, state) => {
// Listen to DOM events
events.on('click', '.button', (e) => {
state.count++;
});

events.on('input', '.search', (e) => {
state.query = e.target.value;
});

// Custom events
events.emit('customEvent', { data: 'value' });

events.on('customEvent', (data) => {
console.log('Event:', data);
});

// Remove listener
events.off('click', '.button', handler);
}


3. effects - Side Effects
Get it by: Adding effects as parameter
What you can do:

(state, effects) => {
// Watch state changes
effects.when('count', (count) => {
console.log('Count changed:', count);
document.noscript = Count: ${count};
});

// Watch with old value
effects.when('status', (newStatus, oldStatus) => {
console.log(${oldStatus} → ${newStatus});
});

// Run once on mount
effects.once('mounted', () => {
console.log('Component mounted!');
});

// Async effects
effects.when('userId', async (userId) => {
const user = await fetchUser(userId);
state.user = user;
});
}


4. weave - Styling (ScrollWeave)
Get it by: Adding weave as parameter
What you can do:

(state, weave) => {
// Apply styles
weave.apply('.element', {
background: 'blue',
padding: '20px'
});

// Conditional
weave.when('.button',
state.isActive,
{ background: 'green' },
{ background: 'gray' }
);

// Animations
weave.fadeIn('.modal', 300);
weave.spring('.card', { transform: 'scale(1)' });
}


5. api - API Calls
Get it by: Adding api as parameter
What you can do:

async (state, api) => {
// Fetch when signal changes
api.when('userId', async (userId) => {
const response = await api.fetch(/api/users/${userId});
const user = await response.json();
state.user = user;
});

// Manual fetch
const response = await api.fetch('/api/data');
const data = await response.json();
state.data = data;
}


6. storage - Persistence
Get it by: Adding storage as
parameter
What you can do:

(state, storage) => {
// Save
storage.persist('settings', state.settings);

// Load (async)
const saved = await storage.load('settings');
if (saved) state.settings = saved;

// Remove
storage.remove('settings');
}


WARNING: storage.load() is async - don't use in state function for initial load!

() => ({
todos: JSON.parse(localStorage.getItem('todos') || '') // Sync!
}),

(state, effects) => {
effects.when('todos', (todos) => {
localStorage.setItem('todos', JSON.stringify(todos)); // Save
});
}


7. validate - Validation
Get it by: Adding validate as parameter
What you can do:

(validate) => {
validate.rule('email',
(value) => /^^\s@+@^\s@+\.^\s@+$/.test(value),
'Invalid email format'
);

validate.rule('age',
(value) => value >= 18,
'Must be 18 or older'
);
}


8. analytics - Analytics Tracking
Get it by: Adding analytics as parameter
What you can do:

(state, analytics) => {
analytics.track('buttonClicked', () => state.clickCount);

analytics.track('pageView', () => ({
page: state.currentPage,
user: state.username
}));
}


# Auto-Detection Rules

The framework detects function type by its signature:

Signature Detected As Gets
({ count }) => ... UI Function State (destructured)
(state) => ... Logic/Effect State proxy
(events) => ... Logic Events
(events, state) => ... Logic Events + State
(state, weave) => ... Styling State + Weave
(state, effects) => ... Effects State + Effects
(state, api) => ... API State + API
() => ({ ... }) State Provider Nothing (returns state)
(state, events, weave, effects, api, storage, validate, analytics) => ... All Contexts All 8!


# State Function Special Rules

Must have ZERO parameters and return object:

// CORRECT
() => ({
count: 0,
user: { name: 'John' }
})

// WRONG - has parameters
(someParam) => ({
count: 0
})

// WRONG - doesn't return object
() => {
const count = 0;
// Missing return!
}


Can include special properties:

() => ({
// Regular state
count: 0,
email: '',

// Computed properties (auto-update!)
computed: {
doubleCount: (state) => state.count 2
},

// Selectors (memoized)
selectors: {
evenCount: (state) => state.count % 2 === 0
},

// Middleware (intercept changes)
middleware: {
count: (oldValue, newValue) => {
return newValue < 0 ? 0 : newValue; // Prevent negative
}
},

// Validation (runtime checks)
validate: {
email: (value) => /^[^\s@]+@[^\s@]+/.test(value) || 'Invalid email'
},

// Options
immutable: true, // Freeze state
debug: {
logChanges: true,
breakOnChange: ['count']
}
})


# HTMLScrollMesh - Quick Reference

HTMLScrollMesh = ScrollMesh Context + HTML template strings

Basic Pattern:

import { HTMLScrollMesh } from 'scrollforge/mesh';

const App = HTMLScrollMesh(
// UI - Write HTML directly
({ count }) => `<button>${count}</button>`,

// Events
(events, state) => {
events.on('click', 'button', () => state.count++);
},

// State
() => ({ count: 0 })
);

App.mount('
#app');


# All 8 Contexts Work Identically

HTMLScrollMesh has the SAME context auto-wiring as ScrollMesh:

(events, state) → Events + State
(state, weave) → State + ScrollWeave styling
(state, effects) → State + Side effects
(state, api) → State + API calls
(storage) → Storage context
(validate) → Validation
(analytics) → Analytics
() => ({ ... }) → State provider (zero params!)
Same rules. Same auto-detection. Just HTML instead of JS
So I made a Full-stack coding framework at 16 years old called ScrollForge: Causal Graph Programming which unifies state, logic, and style in one causal graph.

Hello everyone! So basically I had this idea where the frontend, backend, state, logic etc etc act as nodes within a causal graph, so I went ahead and made a framework on it! Basically it has three engines to be precise with many functions, it took me a longg time to make!

Below is a modest briefing about this framework, however, I must exclaim this is not everything, not even close. If you'd like to see everything, kindly go to the github repo and find the complete guide md to see all of its functions, there are even code snippits in that!

Also if you don't wanna go through the hassle, just go to your root directory and type

npm install scrollforge

Also, I'd love some critique on this ;D

# TL;DR

* Paradigm: Causal Graph Programming (CGP) — you wire functions, not components; the framework auto-detects what each function needs and “snaps” it into a single causal graph (UI ⇄ logic ⇄ effects ⇄ style ⇄ backend).
* Three engines:
* ScrollMesh → component/templating via context auto-wiring (unlimited functions, zero manual wiring).
* ScrollScript → universal signal store (client + server) with actions, watchers, derived signals, time travel.
* ScrollWeave → logic-reactive styling (state/logic drives CSS & animations at runtime).
* Why now: less boilerplate, fewer classes/hooks/providers, more causality visibility.
* Showcase: real-time chat app in < 500 lines (HTML + JS + a tiny server).
* Use cases: dashboards, real-time apps, design systems that react to logic, compact full-stack prototypes.
* One-liner: ScrollForge – Causal Graph Programming: unify state, logic, style, and backend into one reactive graph.

# What is “Causal Graph Programming”?

**The short version:**
Instead of pushing data through props and bouncing events back through callbacks (typical UI frameworks), CGP lets you register as many functions as you want. Each function declares its intent implicitly by its signature (parameters), and the engine auto-provides matching contexts:

1. ({ ...stateProps }) => ui → UI renderer (gets state)
2. (events, state) => { ... } → event logic
3. (state, weave) => { ... } → styling/animation driven by state
4. (state, effects) => { ... } → reactive effects
5. () => ({ ... }) → initial state provider *(…and several more contexts, all optional.)*

Order doesn’t matter. Wiring doesn’t exist. The framework assembles a causal graph out of your functions and keeps it live.

\*\*

**## Why this is different?**

* No props drilling, no provider pyramids, no manual event buses.
* UI, logic, effects, and styles coordinate through shared, reactive signals (ScrollScript) and auto-wired contexts (ScrollMesh).
* Style is not static: ScrollWeave treats CSS as a live system, not a file.

\*\*

# The three engines (in one project)

\*\*

# 1) ScrollMesh — recursive component assembly (auto-wiring):

Write components by passing functions. The engine reads signatures and provides what you need.

import { HTMLScrollMesh } from 'scrollforge/dist/mesh-full.browser.js';

const Counter = HTMLScrollMesh(
// UI (gets state via destructuring)
({ count }) => `<button class="btn">Count: ${count}</button>`,

// Logic (gets events + state)
(events, state) => {
events.on('click', '.btn', () => state.count++);
},

// Initial state
() => ({ count: 0 })
);

Counter.mount('#app');


# 2) ScrollScript — universal data flow (signals, actions, derived):

Client and server share the same API. Signals update; watchers react; derived signals memoize computed values.

// Create global signals
app.Script.signal('messages', []);
app.Script.signal('username', '');
app.Script.watch('messages', (msgs) => console.log('Count:', msgs.length));


# 3)** ScrollWeave **— logic-reactive styling

Let state and logic shape style at runtime.

(state, weave) => {
weave.when('.status',
state.online,
{ background: 'rgba(76, 175, 80, .2)' },
{ background: 'rgba(244, 67, 54, .2)' }
);

// Micro-interaction
weave.spring('.btn', { transform: 'scale(1.0)' }, { stiffness: 200, damping: 20 });
};


# **The <500-line demo: real-time chat

Using this paradigm, we made a fully working chatapp in under 500 lines of code (present in the github repo at the end).

# ScrollMesh Context Auto-Wiring - Deep Dive

**The Revolutionary Breakthrough**

ScrollMesh Context is the most powerful feature in ScrollForge. It allows you to pass UNLIMITED functions that automatically detect what they need and connect themselves.

**How It Works**

import { HTMLScrollMesh } from 'scrollforge/mesh';

const component = HTMLScrollMesh(
function1,
function2,
function3,
// ... add as many as you want!
);


**The framework:**

1. Reads each function's signature (parameters)
2. Detects what contexts each function needs
3. Automatically provides those contexts
4. Wires everything together
5. NO manual configuration required!

# The 8 Available Contexts:

Every function can request any of these contexts by adding them as parameters:

**1. state - Reactive State Proxy**
Get it by: Adding state as parameter
What you can do:

(state) => {
// READ
const count = state.count;
const name = state.user.name;

// WRITE (triggers re-render!)
state.count++;
state.user.name = 'Jane';

// Deep updates work
state.user.profile.settings.theme = 'dark';

// Arrays
state.items.push(newItem);
state.items = [...state.items, newItem];
}


**2. events - Event System**
Get it by: Adding events as parameter
What you can do:

(events, state) => {
// Listen to DOM events
events.on('click', '.button', (e) => {
state.count++;
});

events.on('input', '.search', (e) => {
state.query = e.target.value;
});

// Custom events
events.emit('customEvent', { data: 'value' });

events.on('customEvent', (data) => {
console.log('Event:', data);
});

// Remove listener
events.off('click', '.button', handler);
}


**3. effects - Side Effects**
Get it by: Adding effects as parameter
What you can do:

(state, effects) => {
// Watch state changes
effects.when('count', (count) => {
console.log('Count changed:', count);
document.noscript = `Count: ${count}`;
});

// Watch with old value
effects.when('status', (newStatus, oldStatus) => {
console.log(`${oldStatus} → ${newStatus}`);
});

// Run once on mount
effects.once('mounted', () => {
console.log('Component mounted!');
});

// Async effects
effects.when('userId', async (userId) => {
const user = await fetchUser(userId);
state.user = user;
});
}


**4. weave - Styling (ScrollWeave)**
Get it by: Adding weave as parameter
What you can do:

(state, weave) => {
// Apply styles
weave.apply('.element', {
background: 'blue',
padding: '20px'
});

// Conditional
weave.when('.button',
state.isActive,
{ background: 'green' },
{ background: 'gray' }
);

// Animations
weave.fadeIn('.modal', 300);
weave.spring('.card', { transform: 'scale(1)' });
}


**5. api - API Calls**
Get it by: Adding api as parameter
What you can do:

async (state, api) => {
// Fetch when signal changes
api.when('userId', async (userId) => {
const response = await api.fetch(`/api/users/${userId}`);
const user = await response.json();
state.user = user;
});

// Manual fetch
const response = await api.fetch('/api/data');
const data = await response.json();
state.data = data;
}


**6. storage - Persistence**
Get it by: Adding storage as
parameter
What you can do:

(state, storage) => {
// Save
storage.persist('settings', state.settings);

// Load (async)
const saved = await storage.load('settings');
if (saved) state.settings = saved;

// Remove
storage.remove('settings');
}


*WARNING: storage.load() is async - don't use in state function for initial load!*

() => ({
todos: JSON.parse(localStorage.getItem('todos') || '[]') // Sync!
}),

(state, effects) => {
effects.when('todos', (todos) => {
localStorage.setItem('todos', JSON.stringify(todos)); // Save
});
}


**7. validate - Validation**
Get it by: Adding validate as parameter
What you can do:

(validate) => {
validate.rule('email',
(value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),
'Invalid email format'
);

validate.rule('age',
(value) => value >= 18,
'Must be 18 or older'
);
}


**8. analytics - Analytics Tracking**
Get it by: Adding analytics as parameter
What you can do:

(state, analytics) => {
analytics.track('buttonClicked', () => state.clickCount);

analytics.track('pageView', () => ({
page: state.currentPage,
user: state.username
}));
}


# Auto-Detection Rules

The framework detects function type by its signature:

**Signature Detected As Gets**
({ count }) => ... UI Function State (destructured)
(state) => ... Logic/Effect State proxy
(events) => ... Logic Events
(events, state) => ... Logic Events + State
(state, weave) => ... Styling State + Weave
(state, effects) => ... Effects State + Effects
(state, api) => ... API State + API
() => ({ ... }) State Provider Nothing (returns state)
(state, events, weave, effects, api, storage, validate, analytics) => ... All Contexts All 8!


# State Function Special Rules

Must have ZERO parameters and return object:

// CORRECT
() => ({
count: 0,
user: { name: 'John' }
})

// WRONG - has parameters
(someParam) => ({
count: 0
})

// WRONG - doesn't return object
() => {
const count = 0;
// Missing return!
}


**Can include special properties:**

() => ({
// Regular state
count: 0,
email: '',

// Computed properties (auto-update!)
computed: {
doubleCount: (state) => state.count * 2
},

// Selectors (memoized)
selectors: {
evenCount: (state) => state.count % 2 === 0
},

// Middleware (intercept changes)
middleware: {
count: (oldValue, newValue) => {
return newValue < 0 ? 0 : newValue; // Prevent negative
}
},

// Validation (runtime checks)
validate: {
email: (value) => /^[^\s@]+@[^\s@]+/.test(value) || 'Invalid email'
},

// Options
immutable: true, // Freeze state
debug: {
logChanges: true,
breakOnChange: ['count']
}
})


# HTMLScrollMesh - Quick Reference

HTMLScrollMesh = ScrollMesh Context + HTML template strings

**Basic Pattern:**

import { HTMLScrollMesh } from 'scrollforge/mesh';

const App = HTMLScrollMesh(
// UI - Write HTML directly
({ count }) => `<button>${count}</button>`,

// Events
(events, state) => {
events.on('click', 'button', () => state.count++);
},

// State
() => ({ count: 0 })
);

App.mount('#app');


# All 8 Contexts Work Identically

HTMLScrollMesh has the SAME context auto-wiring as ScrollMesh:

* (events, state) → Events + State
* (state, weave) → State + ScrollWeave styling
* (state, effects) → State + Side effects
* (state, api) → State + API calls
* (storage) → Storage context
* (validate) → Validation
* (analytics) → Analytics
* () => ({ ... }) → State provider (zero params!)
* Same rules. Same auto-detection. Just HTML instead of JS
objects.

# HTML Features

({ items, isLoggedIn, user }) => `
<!-- Conditionals -->
${isLoggedIn ? `<p>Hello ${user.name}</p>` : `<p>Login</p>`}

<!-- Loops -->
<ul>
${items.map(i => `<li>${i.name}</li>`).join('')}
</ul>

<!-- Expressions -->
<p>Total: $${(price * quantity).toFixed(2)}</p>
`


**Key Difference from ScrollMesh Context:**

1. ScrollMesh HTMLScrollMesh
2. { tag: 'div', content: 'Hi' } <div>Hi</div>
3. JS Objects HTML Strings


# ** Using ScrollWeave with HTMLScrollMesh**

**The Pattern:**

HTMLScrollMesh(
// UI function
({ count }) => `<button class="my-btn">${count}</button>`,

// Weave function - gets (state, weave) automatically!
(state, weave) => {
// Apply reactive styles based on state
weave.when('.my-btn',
state.count > 10,
{ background: 'green', fontSize: '2rem' }, // If count > 10
{ background: 'blue', fontSize: '1rem' } // Else
);
},

// Other functions...
(events, state) => {
events.on('click', '.my-btn', () => state.count++);
},

() => ({ count: 0 })
);


**The framework automatically:**

1. Detects (state, weave) signature
2. Provides state proxy + ScrollWeave instance
3. Styles update when state changes
4. Zero manual wiring!

# How It Works

HTMLScrollMesh(
// Function with (state, weave) parameters
(state, weave) => {
// Framework provides:
// - state: reactive component state
// - weave: ScrollWeave instance (app.Weave)

// Use state to drive styles
weave.apply('.element', {
color: state.isActive ? 'green' : 'gray',
fontSize: state.count > 5 ? '2rem' : '1rem'
});
}
);

// Framework auto-detects parameter names!


# Complete Example

const Counter = HTMLScrollMesh(
// UI
({ count, isHigh }) => `
<div class="counter">
<h1 class="display">${count}</h1>
<button class="increment">+</button>
<button class="decrement">-</button>
${isHigh ? `<p class="warning">⚠️ High count!</p>` : ''}
</div>
`,

// Weave - Reactive styling!
(state, weave) => {
// Style changes based on state
weave.when('.display',
state.count > 10,
{
color: 'green',
fontSize: '4rem',
fontWeight: 'bold'
},
{
color: 'blue',
fontSize: '2rem',
fontWeight: 'normal'
}
);

// Button styling
weave.when('.increment',
state.count >= 20,
{ background: '#ccc', cursor: 'not-allowed' },
{ background: '#4CAF50', cursor: 'pointer' }
);

// Animate warning
if (state.isHigh) {
weave.spring('.warning', {
opacity: 1,
transform: 'scale(1)'
});
}
},

// Events
(events, state) => {
events.on('click', '.increment', () => {
if (state.count < 20) state.count++;
});

events.on('click', '.decrement', () => {
if (state.count > 0) state.count--;
});
},

// State
() => ({
count: 0,

computed: {
isHigh: (state) => state.count > 15
}
})
);

Counter.mount('#app');


**State changes → Weave updates styles → UI reflects changes! **

**Key Points**

1. Get weave context: Add weave as parameter after state
2. Signature: (state, weave) => { ... }
3. Framework provides: Your app's app.Weave instance automatically
4. Use state: Access component state to drive styles
5. Reactive: Styles update automatically when state changes

That's it! Just add weave parameter and you get reactive styling!

# Links:

*