Genuine frequently asked questions from developers working with these frameworks.
A: Reactium is the frontend React framework, Actinium is the backend Node.js framework (built on Parse Server + Express). They're designed to work together but can be used independently.
A: npm run local is for development - it runs webpack with HMR, BrowserSync, file watching, and nodemon. npm start just runs the production server (requires npm run build first). Always use npm run local during development.
A: Use npx reactium install @realm/package-name (NOT npm install). This installs from the Reactium registry into reactium_modules/ or actinium_modules/ workspaces. Without arguments, it installs everything from reactiumDependencies/actiniumDependencies in package.json.
A: In Reactium projects, use @atomic-reactor/reactium-core/sdk (or the reactium-core/sdk alias). This is the decorated SDK with all the framework features. The bare @atomic-reactor/reactium-sdk-core is just the primitives used by CLI, Actinium, and as the base for Reactium.
A:
/core- Server-safe utilities (Hook, Cache, Registry, Pulse, Enums)/browser- Browser-only (Component, Zone, Handles, React hooks, Prefs)- Default import has both
Use these subpaths when you need to ensure server/browser compatibility.
A: useSyncState is Reactium's alternative that returns an observable object (not an array). Use it when you want synchronous updates or need to easily pass state around. Use regular useState if you prefer React's standard pattern.
// useSyncState - object with .get()/.set()
const state = useSyncState({ count: 0 });
state.set('count', state.get('count') + 1);
// useState - array [value, setter]
const [count, setCount] = useState(0);
setCount(count + 1);A: useSyncHandle subscribes to Handle changes and re-renders your component. useHandle just retrieves the Handle without subscribing. Almost always use useSyncHandle unless you have a specific reason not to.
A: Use Handles when multiple components need to share the same state. Use local state (useSyncState or useState) when the state is only needed in one component.
A: Reactium provides 16 specialized hooks from @atomic-reactor/reactium-sdk-core/browser:
Most Commonly Used:
useSyncState- Observable local stateuseSyncHandle- Subscribe to shared Handle stateuseAsyncEffect- useEffect with async/await supportuseEventEffect- Subscribe to events with automatic cleanupuseRefs- Manage multiple refs easily
Handle System (for shared state):
useHandle- Get handle (no subscription)useSyncHandle- Get handle (with subscription)useRegisterHandle- Create and register a handleuseSelectHandle- Subscribe to specific handle properties
Component & UI:
useFocusEffect- Run effect when element focuseduseScrollToggle- Toggle on scroll positionuseIsContainer- Check element containmentuseHookComponent- Dynamically load components
Advanced:
useDerivedState- Computed state from other stateuseStatus- Track component lifecycle statususeFullfilledObject- Wait for object properties to resolve
A: The SDK includes browser utilities for common patterns:
Component & Zone System:
Component.register()/Component.get()- Replaceable components by tokenZone/Zones- Render components in designated zonesComponentEvent- Component communication
State & Storage:
Handle- Observable shared state containersPrefs- LocalStorage with reactivity
UI Utilities:
Fullscreen- Fullscreen API wrappercxFactory- ClassName builder- Window/breakpoint utilities - Responsive design helpers
Import from @atomic-reactor/reactium-core/sdk or reactium-core/sdk in your Reactium app.
A: Zones let you render components into designated areas from anywhere in your app:
import { Zone } from 'reactium-core/sdk';
// In your layout
<Zone zone="header" />
<Zone zone="content" />
// From any component, render into zones
Zone.addComponent({
zone: 'header',
component: MyHeaderWidget,
order: 10,
});This is useful for plugin architectures where plugins need to inject UI into host app zones.
A: Check these common issues:
- File name must match pattern:
/(routes?|reactium-routes?.*?)\.jsx?$/ - During
npm run local, manifest auto-regenerates (check console for errors) - Path must start with
/(e.g.,/my-pathnotmy-path) - Component must be imported or registered in Component registry
A: Routes are discovered from files matching: /(routes?|reactium-routes?.*?)\.jsx?$/
Valid examples:
route.jsroutes.jsreactium-route.jsreactium-route-myfeature.jsreactium-routes-admin.js
A: Yes! If the component is registered in the Component registry:
// Register component
Component.register('MyComponent', MyComponent);
// Route can reference by string
export default [
{
path: '/my-path',
component: 'MyComponent', // String reference
},
];A: Add a static loadState method to your component:
export const MyPage = () => {
const handle = useSyncHandle(MyPage.handleId);
const data = handle?.get('data');
return <div>{data}</div>;
};
MyPage.loadState = async ({ params }) => {
const data = await fetchData(params);
return { data };
};
MyPage.handleId = 'MyPageHandle';The return value gets stored in the Handle.
A: Yes, if you register it in the Component registry:
Component.register('MyComponent', MyComponent);
// Then in route:
{ path: '/my-path', component: 'MyComponent' }A: Use Enums.priority.neutral for most plugins. Lower numbers execute first:
Enums.priority.core // -2000 (framework core - executes first)
Enums.priority.highest // -1000
Enums.priority.high // -500
Enums.priority.neutral // 0 (default)
Enums.priority.low // 500
Enums.priority.lowest // 1000Only specify a different priority if you need hooks to run in a specific order.
A:
reactium-hooks-*.js- Browser-side, runs during client bootstrapreactium-boot.js- Server-side, runs during Node/Express bootstrap
Use the appropriate file for your execution context.
A: Common browser hooks: plugin-dependencies, plugin-init, routes-init, register-route, init
Common Actinium hooks: init, start, before-save-{ClassName}, after-save-{ClassName}, before-cloud-{functionName}
Check the CLAUDE/ documentation for complete lists.
A: No! During npm run local, Gulp watches for DDD artifact files and automatically regenerates the manifest. Just add your file and the manifest updates automatically.
A: Never edit it manually - it's auto-generated and your changes will be overwritten.
A: Create a reactium-webpack-*.js file and use the ReactiumWebpack SDK. The old webpack.override.js pattern still works but is deprecated.
A: Actinium requires ES modules. Ensure:
"type": "module"in package.json- Use
import/export, neverrequire/module.exports - Include
.jsextension on relative imports:import './sdk.js'
A: Use Actinium.Cloud.define() (not Parse.Cloud.define()) to get hook integration:
Actinium.Cloud.define(PLUGIN.ID, 'myFunction', async (req) => {
const { param } = req.params;
// req.user, req.master available
return { result: 'success' };
});A: It depends on your security requirements. Use master key for privileged backend operations that should bypass ACLs. For user-scoped operations, use user sessions. Actinium also has a capabilities system - check actinium-core for patterns.
A: No, the @atomic-reactor/reactium-api module handles Parse initialization for you.
A: Usually no - Reactium proxies API requests through /api to avoid CORS. If you make direct API calls bypassing the proxy, you'll need CORS.
A:
const result = await Parse.Cloud.run('functionName', { param: 'value' });A: You're probably using useHandle instead of useSyncHandle. Only useSyncHandle subscribes to changes:
// Won't re-render on changes
const handle = useHandle('MyHandle');
// Will re-render on changes
const handle = useSyncHandle('MyHandle');A: Use useAsyncEffect when you need to await async operations in your effect:
// Regular useEffect - requires wrapper function
useEffect(() => {
(async () => {
const data = await fetchData();
setState(data);
})();
}, []);
// useAsyncEffect - cleaner
useAsyncEffect(async () => {
const data = await fetchData();
setState(data);
}, []);Both work, but useAsyncEffect is more readable for async operations.
A: useEventEffect is specifically for subscribing to Reactium events (like Handle events) with automatic cleanup:
// Subscribe to handle changes
useEventEffect(
handle, // Event target (Handle, ComponentEvent, etc)
{ change: () => console.log('Changed') }, // Event handlers
[handle] // Dependencies
);It automatically unsubscribes on unmount. Use regular useEffect for non-event side effects.
A: Use useRefs instead of creating multiple useRef calls:
const refs = useRefs();
return (
<>
<div ref={el => refs.set('header', el)} />
<div ref={el => refs.set('content', el)} />
<div ref={el => refs.set('footer', el)} />
</>
);
// Access later
const headerEl = refs.get('header');A: Use useSelectHandle when you only need a specific part of a Handle's state and want to optimize re-renders:
// useSyncHandle - re-renders on ANY change to the Handle
const handle = useSyncHandle('UserHandle');
const username = handle?.get('profile.username');
// useSelectHandle - re-renders ONLY when the selected value changes
const { handle, selected: username } = useSelectHandle(
'UserHandle',
'profile.username' // path to specific value
);
// Or use a selector function
const { handle, selected } = useSelectHandle(
'UserHandle',
state => state.get('profile.username')
);Performance benefit: If the Handle has 20 properties but you only care about 1, useSelectHandle prevents unnecessary re-renders when other properties change.
For comprehensive documentation, see the CLAUDE/ directory with detailed framework guides.