Package Reorganization Migration Guide
Since: v1.0.0-beta.2
This guide helps you migrate from v1.0.0-beta.1 to the reorganized package structure in v1.0.0-beta.2, where functionality has been moved to dedicated packages for better separation of concerns.
Overview
In v1.0.0-beta.2, we've reorganized the Coherent.js ecosystem to provide better modularity and separation of concerns:
Note: In current releases,
@coherent.js/coreis intended to be consumed via its top-level entrypoint (import { ... } from '@coherent.js/core'). Historical subpath imports shown in Before snippets (like@coherent.js/core/routeror@coherent.js/core/internal/*) are not part of the supported public API.
New Packages
- @coherent.js/state - Dedicated reactive state management package
- @coherent.js/forms - Comprehensive forms handling with validation
- @coherent.js/devtools - Developer tools and debugging utilities
Moved Functionality
- Client-side router - Moved from
@coherent.js/coreto@coherent.js/client - Lifecycle hooks - Exported from
@coherent.js/corefor better accessibility - Object factory functions - Exported from
@coherent.js/corefor better accessibility - Component cache - Exported from
@coherent.js/corefor better accessibility
Migration Steps
1. Install New Packages
# Install new dedicated packages
pnpm add @coherent.js/state@beta
pnpm add @coherent.js/forms@beta
pnpm add @coherent.js/devtools@beta
# Client router is now in @coherent.js/client (already installed)
2. Update State Management Imports
Before (v1.0.0-beta.1):
import { withState } from '@coherent.js/core';
After (v1.0.0-beta.2):
// For reactive client-side state (new recommended approach)
import { observable, computed, createReactiveState } from '@coherent.js/state';
// For SSR-compatible component state (still available)
import { withState } from '@coherent.js/core';
3. Update Router Imports
Before (v1.0.0-beta.1):
import { createRouter } from '@coherent.js/core/router';
After (v1.0.0-beta.2):
import { createRouter } from '@coherent.js/client/router';
4. Update Lifecycle Hook Imports
Before (v1.0.0-beta.1):
import { ComponentLifecycle, withLifecycle } from '@coherent.js/core/internal/lifecycle';
After (v1.0.0-beta.2):
import { ComponentLifecycle, withLifecycle } from '@coherent.js/core';
5. Update Object Factory Imports
Before (v1.0.0-beta.1):
import { h, createElement } from '@coherent.js/core/internal/factory';
After (v1.0.0-beta.2):
import { h, createElement } from '@coherent.js/core';
6. Update Component Cache Imports
Before (v1.0.0-beta.1):
import { ComponentCache } from '@coherent.js/core/internal/cache';
After (v1.0.0-beta.2):
import { ComponentCache } from '@coherent.js/core';
Code Examples
Reactive State (New Recommended Approach)
Before (v1.0.0-beta.1 - withState):
import { withState } from '@coherent.js/core';
const Counter = withState({ count: 0 })(({ state, setState }) => ({
div: {
children: [
{ p: { text: `Count: ${state.count}` } },
{
button: {
text: 'Increment',
onclick: () => setState({ count: state.count + 1 })
}
}
]
}
}));
After (v1.0.0-beta.2 - @coherent.js/state):
import { observable, computed } from '@coherent.js/state';
// Create reactive state
const count = observable(0);
const doubled = computed(() => count.value * 2);
function Counter() {
const increment = () => {
count.value = count.value + 1;
};
return {
div: {
'data-coherent-component': 'counter',
children: [
{ p: { text: `Count: ${count.value}` } },
{ p: { text: `Doubled: ${doubled.value}` } },
{
button: {
text: 'Increment',
onclick: increment
}
}
]
}
};
}
Client-Side Router
Before (v1.0.0-beta.1):
import { createRouter } from '@coherent.js/core/router';
const router = createRouter({
routes: {
'/': HomePage,
'/about': AboutPage
}
});
After (v1.0.0-beta.2):
import { createRouter } from '@coherent.js/client/router';
const router = createRouter({
routes: {
'/': HomePage,
'/about': AboutPage
}
});
Forms Handling
Before (v1.0.0-beta.1):
// Manual validation in component
function ContactForm() {
const [formData, setFormData] = withState({
email: '',
message: ''
});
const validate = () => {
const errors = {};
if (!formData.email.includes('@')) {
errors.email = 'Invalid email';
}
return errors;
};
return {
form: {
children: [
// Form fields with manual validation
]
}
};
}
After (v1.0.0-beta.2 - @coherent.js/forms):
import { createForm } from '@coherent.js/forms';
import { validators } from '@coherent.js/state';
const contactForm = createForm({
fields: {
email: {
value: '',
validators: [validators.email('Invalid email')]
},
message: {
value: '',
validators: [validators.minLength(10, 'Message too short')]
}
}
});
function ContactForm() {
const submitForm = async () => {
if (contactForm.validate()) {
await submitToAPI(contactForm.values);
}
};
return {
form: {
'data-coherent-component': 'contact-form',
onsubmit: (e) => {
e.preventDefault();
submitForm();
},
children: [
{
input: {
type: 'email',
value: contactForm.fields.email.value,
oninput: (e) => contactForm.setField('email', e.target.value),
className: contactForm.fields.email.error ? 'error' : ''
}
},
{
span: {
text: contactForm.fields.email.error || ''
}
}
]
}
};
}
Migration Checklist
Core Package Changes
- Update router imports from
@coherent.js/core/routerto@coherent.js/client/router - Update lifecycle hook imports to use top-level exports
- Update object factory imports to use top-level exports
- Update component cache imports to use top-level exports
State Management
- Install
@coherent.js/statepackage - Replace
withStatewith reactive state for client-side components (optional but recommended) - Keep using
withStatefrom@coherent.js/corefor SSR-compatible state
Forms
- Install
@coherent.js/formspackage - Replace manual form validation with
@coherent.js/forms - Update form components to use new form utilities
Development Tools
- Install
@coherent.js/devtoolspackage - Update devtools integration if used
Testing
- Run tests to ensure all imports work correctly
- Verify router functionality
- Check state management behavior
- Test form validation and submission
Breaking Changes
Removed Internal Imports
@coherent.js/core/internal/*paths are no longer accessible- All functionality is now exported from top-level package entry points
Router Move
- Client-side router moved from
@coherent.js/coreto@coherent.js/client - No API changes, only import path changes
State Management Evolution
withStatestill available in@coherent.js/corefor SSR compatibility- New reactive state system in
@coherent.js/statefor client-side applications
Benefits of the Reorganization
Better Separation of Concerns
- Dedicated packages for specific functionality
- Reduced complexity in core package
- Clearer module boundaries
Improved Performance
- Only import what you need
- Smaller bundle sizes with code splitting
- Better tree-shaking support
Enhanced Developer Experience
- More focused documentation
- Better TypeScript support per package
- Clearer dependency relationships
Easier Maintenance
- Independent release cycles
- Targeted bug fixes
- Feature-specific versioning
Support and Questions
If you encounter issues during migration:
- Check the API Reference for updated import paths
- Review the Reactive State Guide for new state management patterns
- Consult the Client Router Guide for router updates
- File issues on GitHub with migration-related problems
The reorganization is designed to make Coherent.js more modular and maintainable while providing better tools for building modern web applications.