@fluixi/core 1.0.0-alpha.53 β†’ 1.0.0-alpha.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +137 -479
  2. package/package.json +14 -12
package/README.md CHANGED
@@ -8,33 +8,31 @@
8
8
 
9
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-22c55e.svg)](./LICENSE)
10
10
  ![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white)
11
- ![Registry](https://img.shields.io/badge/registry-GitHub%20Packages-181717?logo=github)
12
- ![Framework](https://img.shields.io/badge/framework-Fluixi%20%F0%9F%AB%96-ff6b35)
11
+ [![npm](https://img.shields.io/npm/v/@fluixi/core?logo=npm)](https://www.npmjs.com/package/@fluixi/core)
13
12
 
14
13
  ---
15
14
 
16
- A modern, reactive framework for building web applications with [lit-html](https://lit.dev) and fine-grained reactivity, inspired by [SolidJS](https://www.solidjs.com/).
15
+ A modern, reactive UI framework with JSX, fine-grained reactivity, routing and SSR. Components compile to direct DOM operations β€” no virtual DOM, surgical updates.
17
16
 
18
17
  ## Features
19
18
 
20
- - πŸš€ **Fine-grained Reactivity** - Powered by `@fluixi/reactive` for efficient, surgical updates
21
- - 🎯 **lit-html Integration** - Leverage the power and simplicity of lit-html templates
22
- - πŸ”„ **Control Flow Components** - Show, For, Switch, Portal, and Dynamic components
19
+ - πŸš€ **Fine-grained Reactivity** - Signals and memos drive surgical DOM updates, no virtual DOM
20
+ - 🧩 **JSX** - Compiled to direct DOM instructions via `@fluixi/vite-plugin`
21
+ - πŸ”„ **Control Flow Components** - Show, For, Switch, Portal, and Dynamic
23
22
  - πŸ›£οΈ **Built-in Router** - Client-side routing with nested routes and lazy loading
24
- - πŸ“‘ **Resource Management** - Async data fetching with automatic loading states
23
+ - πŸ“‘ **Resource Management** - Async data fetching with automatic loading states + Suspense
25
24
  - 🎭 **Context API** - Share state across component trees without prop drilling
25
+ - πŸ–₯️ **SSR + Hydration** - Server rendering with flash-free hydration (via `@fluixi/start`)
26
26
  - πŸ—οΈ **TypeScript First** - Full type safety and excellent IDE support
27
- - πŸ› οΈ **CLI Tools** - Project and component generators for rapid development
28
- - πŸ“¦ **Zero Runtime Overhead** - Compile-time optimizations for minimal bundle size
29
27
 
30
28
  ## Installation
31
29
 
32
30
  ```bash
33
- npm install @fluixi/core @fluixi/reactive lit
31
+ npm install @fluixi/core @fluixi/reactive
34
32
  # or
35
- yarn add @fluixi/core @fluixi/reactive lit
33
+ pnpm add @fluixi/core @fluixi/reactive
36
34
  # or
37
- pnpm add @fluixi/core @fluixi/reactive lit
35
+ yarn add @fluixi/core @fluixi/reactive
38
36
  ```
39
37
 
40
38
  ## Quick Start
@@ -42,570 +40,230 @@ pnpm add @fluixi/core @fluixi/reactive lit
42
40
  ### Creating a New Project
43
41
 
44
42
  ```bash
45
- # Using the CLI
46
- npx @fluixi/core new my-app
47
-
48
- # Or install globally
49
- npm install -g @fluixi/core
50
- fluixi new my-app
43
+ npm create fluixi my-app
44
+ # or: pnpm create fluixi my-app
51
45
  ```
52
46
 
53
47
  ### Basic Example
54
48
 
55
- ```typescript
56
- import { createSignal, render, html } from '@fluixi/core';
49
+ ```tsx
50
+ import { createSignal, render } from '@fluixi/core';
57
51
 
58
52
  const Counter = () => {
59
53
  const [count, setCount] = createSignal(0);
60
54
 
61
- return html`
55
+ return (
62
56
  <div>
63
- <h1>Count: ${count()}</h1>
64
- <button @click=${() => setCount(count() + 1)}>Increment</button>
65
- <button @click=${() => setCount(count() - 1)}>Decrement</button>
66
- <button @click=${() => setCount(0)}>Reset</button>
57
+ <h1>Count: {count()}</h1>
58
+ <button onClick={() => setCount(count() + 1)}>Increment</button>
59
+ <button onClick={() => setCount(count() - 1)}>Decrement</button>
60
+ <button onClick={() => setCount(0)}>Reset</button>
67
61
  </div>
68
- `;
62
+ );
69
63
  };
70
64
 
71
- render(Counter, document.getElementById('app')!);
65
+ render(() => <Counter />, document.getElementById('app')!);
72
66
  ```
73
67
 
68
+ > JSX is compiled by `@fluixi/vite-plugin`. Scaffold a ready-to-run app with `npm create fluixi`.
69
+
74
70
  ## Core Concepts
75
71
 
76
72
  ### Signals
77
73
 
78
- Signals are the foundation of reactivity in Fluixi. They create reactive state that automatically updates the UI when changed.
74
+ Signals are reactive state. Reading one inside an effect or JSX subscribes to it; setting it updates only what depends on it.
79
75
 
80
- ```typescript
76
+ ```tsx
81
77
  import { createSignal, createEffect } from '@fluixi/core';
82
78
 
83
79
  const [count, setCount] = createSignal(0);
84
80
  const [name, setName] = createSignal('Alice');
85
81
 
86
- // Effects run automatically when dependencies change
87
82
  createEffect(() => {
88
- console.log(`${name()} has counted to ${count()}`);
83
+ console.log(`${name()} counted to ${count()}`);
89
84
  });
90
85
 
91
- setCount(5); // Logs: "Alice has counted to 5"
92
- setName('Bob'); // Logs: "Bob has counted to 5"
86
+ setCount(5); // "Alice counted to 5"
87
+ setName('Bob'); // "Bob counted to 5"
93
88
  ```
94
89
 
95
90
  ### Components
96
91
 
97
- Components are pure functions that return lit-html templates. They can use reactive primitives to manage state.
92
+ Components are plain functions that return JSX. Props are reactive β€” read them where you use them.
98
93
 
99
- ```typescript
100
- import { html, createSignal, Component, ComponentProps } from '@fluixi/core';
101
-
102
- interface GreetingProps extends ComponentProps {
103
- initialName?: string;
94
+ ```tsx
95
+ function Greeting(props: { name: string }) {
96
+ return <h1>Hello, {props.name}!</h1>;
104
97
  }
105
98
 
106
- const Greeting: Component<GreetingProps> = (props) => {
107
- const [name, setName] = createSignal(props.initialName || 'World');
108
-
109
- return html`
110
- <div>
111
- <h1>Hello, ${name()}!</h1>
112
- <input
113
- type="text"
114
- .value=${name()}
115
- @input=${(e: Event) => setName((e.target as HTMLInputElement).value)}
116
- />
117
- </div>
118
- `;
119
- };
99
+ // <Greeting name="World" />
120
100
  ```
121
101
 
122
102
  ### Control Flow
123
103
 
124
- Fluixi provides control flow components for conditional rendering and lists.
104
+ Use control-flow components instead of ternaries and `.map()` so updates stay fine-grained.
125
105
 
126
- #### Show - Conditional Rendering
106
+ ```tsx
107
+ import { Show, For, Switch, Match } from '@fluixi/core';
127
108
 
128
- ```typescript
129
- import { Show, createSignal, html } from '@fluixi/core';
109
+ // Show β€” conditional rendering (child callback receives the narrowed value)
110
+ <Show when={() => user()} fallback={<p>Please log in</p>}>
111
+ {(u) => <p>Welcome, {u.name}!</p>}
112
+ </Show>
130
113
 
131
- const UserProfile = () => {
132
- const [user, setUser] = createSignal<User | null>(null);
133
- const [loading, setLoading] = createSignal(true);
114
+ // For β€” keyed list rendering (index is an accessor)
115
+ <For each={todos()}>
116
+ {(todo, i) => <li>{i() + 1}. {todo.text}</li>}
117
+ </For>
134
118
 
135
- return html`
136
- ${Show({
137
- when: loading,
138
- fallback: Show({
139
- when: user,
140
- fallback: html`<p>No user found</p>`,
141
- children: (u) => html`<p>Welcome, ${u.name}!</p>`
142
- }),
143
- children: html`<p>Loading...</p>`
144
- })}
145
- `;
146
- };
119
+ // Switch / Match β€” multi-branch
120
+ <Switch fallback={<p>Idle</p>}>
121
+ <Match when={() => status() === 'loading'}><p>Loading…</p></Match>
122
+ <Match when={() => status() === 'success'}><p>Done!</p></Match>
123
+ <Match when={() => status() === 'error'}><p>Error</p></Match>
124
+ </Switch>
147
125
  ```
148
126
 
149
- #### For - List Rendering
150
-
151
- ```typescript
152
- import { For, createSignal, html } from '@fluixi/core';
153
-
154
- const TodoList = () => {
155
- const [todos, setTodos] = createSignal([
156
- { id: 1, text: 'Learn Fluixi', done: false },
157
- { id: 2, text: 'Build an app', done: false },
158
- ]);
159
-
160
- return html`
161
- <ul>
162
- ${For({
163
- each: todos,
164
- children: (todo, index) => html`
165
- <li>
166
- <input
167
- type="checkbox"
168
- .checked=${todo.done}
169
- @change=${(e) => {
170
- const newTodos = [...todos()];
171
- newTodos[index].done = e.target.checked;
172
- setTodos(newTodos);
173
- }}
174
- />
175
- ${todo.text}
176
- </li>
177
- `
178
- })}
179
- </ul>
180
- `;
181
- };
182
- ```
127
+ `Portal`, `Dynamic`, `Index`, and `ErrorBoundary` are also exported.
183
128
 
184
- #### Switch/Match - Multiple Conditions
129
+ ### Resources & Suspense
185
130
 
186
- ```typescript
187
- import { Switch, Match, createSignal, html } from '@fluixi/core';
131
+ `createResource` fetches async data and tracks loading/error. `<Suspense>` shows a fallback while it's pending (works on the client and during SSR).
188
132
 
189
- const StatusView = () => {
190
- const [status, setStatus] = createSignal<'loading' | 'success' | 'error'>('loading');
133
+ ```tsx
134
+ import { createSignal, createResource, Suspense } from '@fluixi/core';
191
135
 
192
- return html`
193
- ${Switch({
194
- children: [
195
- Match({ when: () => status() === 'loading', children: html`<p>Loading...</p>` }),
196
- Match({ when: () => status() === 'success', children: html`<p>Success!</p>` }),
197
- Match({ when: () => status() === 'error', children: html`<p>Error!</p>` })
198
- ]
199
- })}
200
- `;
201
- };
202
- ```
136
+ function UserCard() {
137
+ const [id] = createSignal(1);
138
+ const [user] = createResource(id, (id) =>
139
+ fetch(`/api/users/${id}`).then((r) => r.json())
140
+ );
203
141
 
204
- #### Portal - Render Outside Hierarchy
205
-
206
- ```typescript
207
- import { Portal, createSignal, Show, html } from '@fluixi/core';
208
-
209
- const Modal = () => {
210
- const [isOpen, setIsOpen] = createSignal(false);
211
-
212
- return html`
213
- <button @click=${() => setIsOpen(true)}>Open Modal</button>
214
-
215
- ${Show({
216
- when: isOpen,
217
- children: Portal({
218
- children: html`
219
- <div class="modal-overlay">
220
- <div class="modal-content">
221
- <h2>Modal Title</h2>
222
- <p>Modal content goes here</p>
223
- <button @click=${() => setIsOpen(false)}>Close</button>
224
- </div>
225
- </div>
226
- `
227
- })
228
- })}
229
- `;
230
- };
231
- ```
232
-
233
- ### Resources
234
-
235
- Resources handle async data fetching with built-in loading and error states.
236
-
237
- ```typescript
238
- import { createResource, Show, html } from '@fluixi/core';
239
-
240
- interface User {
241
- id: number;
242
- name: string;
243
- email: string;
142
+ return (
143
+ <Suspense fallback={<p>Loading…</p>}>
144
+ <p>{user()?.name}</p>
145
+ </Suspense>
146
+ );
244
147
  }
245
-
246
- const fetchUser = async (id: number): Promise<User> => {
247
- const response = await fetch(`/api/users/${id}`);
248
- return response.json();
249
- };
250
-
251
- const UserDetail = () => {
252
- const [userId, setUserId] = createSignal(1);
253
- const [user, { refetch }] = createResource(() => userId(), fetchUser);
254
-
255
- return html`
256
- ${Show({
257
- when: user.loading,
258
- fallback: Show({
259
- when: user.error,
260
- fallback: Show({
261
- when: user,
262
- children: (u) => html`
263
- <div>
264
- <h2>${u.name}</h2>
265
- <p>${u.email}</p>
266
- <button @click=${refetch}>Refresh</button>
267
- </div>
268
- `
269
- }),
270
- children: html`<p>Error: ${user.error?.message}</p>`
271
- }),
272
- children: html`<p>Loading user...</p>`
273
- })}
274
- `;
275
- };
276
148
  ```
277
149
 
278
- ### Context API
150
+ ### Context
279
151
 
280
- Share state across component trees without prop drilling.
152
+ Share state down the tree without prop drilling.
281
153
 
282
- ```typescript
283
- import { createContext, useContext, Provider, html } from '@fluixi/core';
154
+ ```tsx
155
+ import { createContext, useContext } from '@fluixi/core';
284
156
 
285
- interface Theme {
286
- primaryColor: string;
287
- secondaryColor: string;
288
- }
157
+ const ThemeContext = createContext<'light' | 'dark'>('light');
289
158
 
290
- const ThemeContext = createContext<Theme>({
291
- primaryColor: '#007bff',
292
- secondaryColor: '#6c757d'
293
- });
159
+ function App() {
160
+ return (
161
+ <ThemeContext.Provider value="dark">
162
+ <Toolbar />
163
+ </ThemeContext.Provider>
164
+ );
165
+ }
294
166
 
295
- const ThemedButton = () => {
167
+ function Toolbar() {
296
168
  const theme = useContext(ThemeContext);
297
-
298
- return html`
299
- <button style="background: ${theme.primaryColor}">
300
- Themed Button
301
- </button>
302
- `;
303
- };
304
-
305
- const App = () => {
306
- const theme = { primaryColor: '#28a745', secondaryColor: '#dc3545' };
307
-
308
- return Provider({
309
- context: ThemeContext,
310
- value: theme,
311
- children: html`
312
- <div>
313
- <h1>My App</h1>
314
- ${ThemedButton()}
315
- </div>
316
- `
317
- });
318
- };
169
+ return <div class={theme}>…</div>;
170
+ }
319
171
  ```
320
172
 
321
173
  ### Router
322
174
 
323
- Built-in client-side routing with nested routes and lazy loading.
175
+ The router takes a `routes` config; nested routes render through `<Outlet />`, and `lazy()` code-splits.
324
176
 
325
- ```typescript
326
- import { createRouter, Router, Link, useParams, html } from '@fluixi/core';
327
-
328
- const Home = () => html`<h1>Home Page</h1>`;
329
-
330
- const UserDetail = () => {
331
- const params = useParams();
332
- return html`<h1>User ${params.id}</h1>`;
333
- };
177
+ ```tsx
178
+ import { render } from '@fluixi/core';
179
+ import { Router, Outlet, lazy } from '@fluixi/core/router-next';
334
180
 
335
181
  const routes = [
336
- { path: '/', component: Home },
337
- { path: '/users/:id', component: UserDetail },
338
- { path: '/about', component: () => html`<h1>About</h1>` }
339
- ];
340
-
341
- const App = () => {
342
- const router = createRouter(routes);
343
-
344
- return Router({
345
- router,
346
- children: html`
347
- <div>
348
- <nav>
349
- ${Link({ href: '/', children: 'Home' })}
350
- ${Link({ href: '/about', children: 'About' })}
351
- </nav>
352
- <main id="content"></main>
182
+ {
183
+ path: '/',
184
+ component: () => (
185
+ <div class="app">
186
+ <nav>…</nav>
187
+ <Outlet />
353
188
  </div>
354
- `
355
- });
356
- };
357
- ```
358
-
359
- ## CLI Commands
360
-
361
- ### Create a New Project
362
-
363
- ```bash
364
- # Interactive mode
365
- fluixi new
366
-
367
- # With options
368
- fluixi new my-app --template full
369
- ```
370
-
371
- ### Generate a Component
372
-
373
- ```bash
374
- # Interactive mode
375
- fluixi generate component
189
+ ),
190
+ children: [
191
+ { path: '', component: () => <h1>Home</h1> },
192
+ { path: 'about', component: lazy(() => import('./About')) },
193
+ ],
194
+ },
195
+ ];
376
196
 
377
- # With options
378
- fluixi g c MyComponent --type with-state --path components/MyComponent/MyComponent.ts
197
+ render(() => <Router routes={routes} />, document.getElementById('app')!);
379
198
  ```
380
199
 
381
- Component types:
382
- - `basic` - Simple component
383
- - `with-state` - Component with reactive state
384
- - `with-resource` - Component with async data fetching
385
- - `with-router` - Component with router integration
386
- - `full` - Full-featured component with all features
387
-
388
200
  ## Lifecycle Hooks
389
201
 
390
- ```typescript
391
- import { onMount, onUnmount, createSignal, html } from '@fluixi/core';
202
+ ```tsx
203
+ import { onMount, onCleanup } from '@fluixi/core';
392
204
 
393
- const MyComponent = () => {
394
- const [count, setCount] = createSignal(0);
205
+ function Clock() {
206
+ const [now, setNow] = createSignal(Date.now());
395
207
 
396
208
  onMount(() => {
397
- console.log('Component mounted');
398
- const interval = setInterval(() => setCount(c => c + 1), 1000);
399
-
400
- // Cleanup function
401
- return () => {
402
- console.log('Component unmounting');
403
- clearInterval(interval);
404
- };
405
- });
406
-
407
- onUnmount(() => {
408
- console.log('Additional cleanup');
209
+ const id = setInterval(() => setNow(Date.now()), 1000);
210
+ onCleanup(() => clearInterval(id));
409
211
  });
410
212
 
411
- return html`<div>Count: ${count()}</div>`;
412
- };
213
+ return <time>{new Date(now()).toLocaleTimeString()}</time>;
214
+ }
413
215
  ```
414
216
 
415
- ## Advanced Patterns
416
-
417
- ### Derived State (Memos)
217
+ ## Derived State & Batching
418
218
 
419
- ```typescript
420
- import { createSignal, createMemo, html } from '@fluixi/core';
219
+ ```tsx
220
+ import { createSignal, createMemo, batch } from '@fluixi/core';
421
221
 
422
- const ExpensiveCalculation = () => {
423
- const [a, setA] = createSignal(1);
424
- const [b, setB] = createSignal(2);
222
+ const [first, setFirst] = createSignal('Ada');
223
+ const [last, setLast] = createSignal('Lovelace');
425
224
 
426
- // Memo caches the result and only recalculates when dependencies change
427
- const sum = createMemo(() => {
428
- console.log('Calculating sum...');
429
- return a() + b();
430
- });
225
+ // Memo β€” cached, recomputes only when a dependency changes
226
+ const fullName = createMemo(() => `${first()} ${last()}`);
431
227
 
432
- return html`
433
- <div>
434
- <p>Sum: ${sum()}</p>
435
- <button @click=${() => setA(a() + 1)}>Increment A</button>
436
- <button @click=${() => setB(b() + 1)}>Increment B</button>
437
- </div>
438
- `;
439
- };
228
+ // Batch β€” coalesce multiple writes into one update
229
+ batch(() => {
230
+ setFirst('Grace');
231
+ setLast('Hopper');
232
+ });
440
233
  ```
441
234
 
442
- ### Batched Updates
235
+ ## SSR
443
236
 
444
- ```typescript
445
- import { createSignal, batch, html } from '@fluixi/core';
237
+ Server rendering, hydration, file-based routing and the dev/build tooling live in [`@fluixi/start`](https://www.npmjs.com/package/@fluixi/start). Scaffold an SSR app with `npm create fluixi` and pick the SSR template.
446
238
 
447
- const BatchExample = () => {
448
- const [firstName, setFirstName] = createSignal('John');
449
- const [lastName, setLastName] = createSignal('Doe');
239
+ ## TypeScript
450
240
 
451
- const updateName = () => {
452
- batch(() => {
453
- setFirstName('Jane');
454
- setLastName('Smith');
455
- }); // UI updates only once
456
- };
241
+ Fluixi is written in TypeScript and ships full types. Configure JSX in your `tsconfig.json`:
457
242
 
458
- return html`
459
- <div>
460
- <p>${firstName()} ${lastName()}</p>
461
- <button @click=${updateName}>Update Name</button>
462
- </div>
463
- `;
464
- };
465
- ```
466
-
467
- ### Error Boundaries
468
-
469
- ```typescript
470
- import { createSignal, Show, html } from '@fluixi/core';
471
-
472
- const ErrorBoundary = (props: { children: any }) => {
473
- const [error, setError] = createSignal<Error | null>(null);
474
-
475
- try {
476
- return html`
477
- ${Show({
478
- when: () => !error(),
479
- fallback: html`<div>Error: ${error()?.message}</div>`,
480
- children: props.children
481
- })}
482
- `;
483
- } catch (e) {
484
- setError(e as Error);
485
- return html`<div>Error: ${(e as Error).message}</div>`;
243
+ ```json
244
+ {
245
+ "compilerOptions": {
246
+ "jsx": "preserve",
247
+ "jsxImportSource": "@fluixi/jsx"
486
248
  }
487
- };
488
- ```
489
-
490
- ## API Reference
491
-
492
- ### Core
493
-
494
- - `createSignal(initialValue, options?)` - Create a reactive signal
495
- - `createEffect(fn)` - Run side effects when dependencies change
496
- - `createMemo(fn)` - Create derived reactive state
497
- - `createComponent(fn)` - Create a component with lifecycle management
498
- - `render(component, container)` - Render a component into the DOM
499
- - `onMount(fn)` - Run code when component mounts
500
- - `onUnmount(fn)` - Run code when component unmounts
501
- - `batch(fn)` - Batch multiple updates together
502
- - `untrack(fn)` - Run code without tracking dependencies
503
-
504
- ### Control Flow
505
-
506
- - `Show({ when, fallback?, children })` - Conditional rendering
507
- - `For({ each, fallback?, children })` - List rendering
508
- - `Index({ each, fallback?, children })` - Non-keyed list rendering
509
- - `Switch({ fallback?, children })` - Multiple condition branches
510
- - `Match({ when, children })` - Condition branch in Switch
511
- - `Portal({ mount?, children })` - Render outside component tree
512
- - `Dynamic({ component, props?, children? })` - Render dynamic components
513
-
514
- ### Context
515
-
516
- - `createContext(defaultValue, name?)` - Create a context
517
- - `useContext(context)` - Access context value
518
- - `Provider({ context, value, children })` - Provide context value
519
-
520
- ### Resources
521
-
522
- - `createResource(source, fetcher, options?)` - Create async resource
523
- - `createResources([...])` - Create multiple resources
524
- - `createLazyResource(source, fetcher, options?)` - Create lazy resource
525
-
526
- ### Router
527
-
528
- - `createRouter(routes, options?)` - Create router instance
529
- - `Router({ router, children })` - Router provider component
530
- - `Link({ href, children })` - Navigation link
531
- - `useRouter()` - Access router instance
532
- - `useLocation()` - Access current location
533
- - `useNavigate()` - Get navigation function
534
- - `useParams()` - Get route parameters
535
- - `useQuery()` - Get query parameters
536
-
537
- ## TypeScript Support
538
-
539
- Fluixi is written in TypeScript and provides full type safety:
540
-
541
- ```typescript
542
- import { Component, ComponentProps, createSignal } from '@fluixi/core';
543
-
544
- interface UserProps extends ComponentProps {
545
- userId: number;
546
- onUserLoad?: (user: User) => void;
547
- }
548
-
549
- interface User {
550
- id: number;
551
- name: string;
552
- email: string;
553
249
  }
554
-
555
- const UserComponent: Component<UserProps> = (props) => {
556
- const [user, setUser] = createSignal<User | null>(null);
557
-
558
- // TypeScript knows the types of all signals and props
559
- return html`<div>${user()?.name}</div>`;
560
- };
561
250
  ```
562
251
 
563
- ## Comparison with Other Frameworks
564
-
565
- ### vs React
566
-
567
- - βœ… No virtual DOM - direct DOM updates for better performance
568
- - βœ… True fine-grained reactivity without re-renders
569
- - βœ… Simpler mental model - no hooks rules or dependency arrays
570
- - βœ… Smaller bundle size
571
- - ⚠️ Smaller ecosystem (but growing!)
572
-
573
- ### vs SolidJS
574
-
575
- - βœ… Similar reactivity model and API
576
- - βœ… Uses lit-html for familiar template syntax
577
- - βœ… Integrated with @fluixi/reactive library
578
- - ⚠️ Different template syntax (lit-html vs JSX)
579
-
580
- ### vs Vue
581
-
582
- - βœ… More explicit reactivity with signals
583
- - βœ… Better TypeScript inference
584
- - βœ… Lighter weight
585
- - ⚠️ No single-file components
252
+ ## Ecosystem
586
253
 
587
- ## Contributing
588
-
589
- We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
254
+ | Package | Purpose |
255
+ | --- | --- |
256
+ | `@fluixi/core` | Framework faΓ§ade β€” components, control flow, router, render |
257
+ | `@fluixi/reactive` | Signals, memos, effects, store |
258
+ | `@fluixi/dom` | The DOM rendering runtime |
259
+ | `@fluixi/start` | SSR, hydration, file routing, dev/build |
260
+ | `@fluixi/vite-plugin` | JSX compile (Vite) |
261
+ | `create-fluixi` | App scaffolder (`npm create fluixi`) |
590
262
 
591
263
  ## License
592
264
 
593
- MIT License - see [LICENSE](LICENSE) for details.
594
-
595
- ## Credits
596
-
597
- Fluixi is inspired by:
598
- - [SolidJS](https://www.solidjs.com/) - For the reactivity model and API design
599
- - [Lit](https://lit.dev/) - For the template system
600
- - The [TC39 Signals Proposal](https://github.com/tc39/proposal-signals)
265
+ MIT
601
266
 
602
267
  ## Links
603
268
 
604
- - [Documentation](https://github.com/your-org/fluixi/docs)
605
- - [Examples](https://github.com/your-org/fluixi/examples)
606
- - [GitHub](https://github.com/your-org/fluixi)
607
269
  - [npm](https://www.npmjs.com/package/@fluixi/core)
608
-
609
- ---
610
-
611
- Made with β˜• by the Adafri team
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@fluixi/core",
3
- "version": "1.0.0-alpha.53",
3
+ "version": "1.0.0-alpha.55",
4
+ "license": "MIT",
4
5
  "description": "Solid-Compatible Fine-Grained UI Framework",
5
6
  "private": false,
6
7
  "publishConfig": {
@@ -18,7 +19,8 @@
18
19
  "files": [
19
20
  "dist",
20
21
  "types",
21
- "README.md"
22
+ "README.md",
23
+ "LICENSE"
22
24
  ],
23
25
  "exports": {
24
26
  "./types": {
@@ -84,16 +86,16 @@
84
86
  "lit": "^3.0.0",
85
87
  "lit-html": "^3.0.0",
86
88
  "vite-plugin-node-polyfills": "^0.25.0",
87
- "@fluixi/compiler": "1.0.0-alpha.53",
88
- "@fluixi/dom": "1.0.0-alpha.53",
89
- "@fluixi/jsx": "1.0.0-alpha.53",
90
- "@fluixi/lit": "1.0.0-alpha.53",
91
- "@fluixi/vite-plugin": "1.0.0-alpha.53",
92
- "@fluixi/reactive": "1.0.0-alpha.53",
93
- "@fluixi/router": "0.1.2-alpha.1",
94
- "@fluixi/server": "1.0.0-alpha.53",
95
- "@fluixi/utils": "1.0.0-alpha.53",
96
- "@fluixi/head": "0.1.0-alpha.20"
89
+ "@fluixi/compiler": "1.0.0-alpha.55",
90
+ "@fluixi/dom": "1.0.0-alpha.55",
91
+ "@fluixi/jsx": "1.0.0-alpha.55",
92
+ "@fluixi/lit": "1.0.0-alpha.55",
93
+ "@fluixi/vite-plugin": "1.0.0-alpha.55",
94
+ "@fluixi/reactive": "1.0.0-alpha.55",
95
+ "@fluixi/router": "0.1.2-alpha.3",
96
+ "@fluixi/server": "1.0.0-alpha.55",
97
+ "@fluixi/utils": "1.0.0-alpha.55",
98
+ "@fluixi/head": "0.1.0-alpha.22"
97
99
  },
98
100
  "devDependencies": {
99
101
  "@bambiste/mix-builder": "next",