Skip to content

Framework Comparison

This guide helps you understand the differences between React and Svelte when using Annota.

import {
AnnotaProvider,
Viewer as AnnotaViewer,
Annotator,
AnnotationPopup,
} from "annota/react";
import {
useAnnotator,
useAnnotations,
useSelection,
useTool,
} from "annota/react";
import { useAnnotator } from "annota/react";
function MyComponent() {
const annotator = useAnnotator();
if (!annotator) return null;
return <div>Annotations: {annotator.state.store.all().length}</div>;
}
import { useAnnotations } from "annota/react";
function AnnotationList() {
const annotations = useAnnotations();
return (
<ul>
{annotations.map((ann) => (
<li key={ann.id}>{ann.shape.type}</li>
))}
</ul>
);
}
import { useSelection } from "annota/react";
function SelectionInfo() {
const selection = useSelection();
return <p>Selected: {selection.length}</p>;
}
import { useTool } from "annota/react";
import { RectangleTool } from "annota/tools";
function ToolController({ viewer }) {
const tool = new RectangleTool();
useTool({
viewer,
handler: tool,
enabled: true,
});
return null;
}
import { AnnotaProvider, Viewer as AnnotaViewer, Annotator } from "annota/react";
function App() {
const [viewer, setViewer] = useState(null);
return (
<AnnotaProvider slideId="my-slide">
<AnnotaViewer onViewerReady={setViewer} />
<Annotator viewer={viewer} />
</AnnotaProvider>
);
}
ReactSvelte
{condition && <Component />}{#if condition}<Component />{/if}
{condition ? <A /> : <B />}{#if condition}<A />{:else}<B />{/if}
{!condition && <Component />}{#if !condition}<Component />{/if}
ReactSvelte
{items.map(item => <div key={item.id}>{item.name}</div>)}{#each items as item (item.id)}<div>{item.name}</div>{/each}
Use key prop for keysUse (item.id) for keys
ReactSvelte
const [state, setState] = useState()let state = $state()
const memo = useMemo(() => ..., [deps])const memo = $derived(...)
useEffect(() => ..., [deps])$effect(() => ...)
useCallback(fn, [deps])Function declarations (no deps)
import { useAnnotator } from "annota/react";
import { useEffect } from "react";
function LoadAnnotations({ slideId }) {
const annotator = useAnnotator();
useEffect(() => {
if (!annotator) return;
fetch(`/api/annotations/${slideId}`)
.then(res => res.json())
.then(anns => annotator.addAnnotations(anns));
}, [annotator, slideId]);
return null;
}
<Annotator
viewer={viewer}
style={(annotation) => ({
fill: annotation.properties?.type === "tumor" ? "#FF0000" : "#00FF00",
fillOpacity: 0.3,
})}
/>
  1. Replace hooks with stores:

    • useAnnotator() → getAnnotator()() with $derived
    • useAnnotations() → annotations()
    • useSelection() → selection()
  2. Update state syntax:

    • useState() → $state()
    • useMemo() → $derived()
    • useEffect() → $effect()
  3. Change JSX to Svelte syntax:

    • className → class
    • style={{...}} → style="..."
    • onClick={...} → onclick={...}
  4. Update imports:

    • from "annota/react" → from "annota/svelte"
  1. Replace stores with hooks:

    • annotations() → useAnnotations()
    • selection() → useSelection()
    • getAnnotator()() → useAnnotator()
  2. Update state syntax:

    • $state() → useState()
    • $derived() → useMemo()
    • $effect() → useEffect()
  3. Change Svelte syntax to JSX:

    • class → className
    • onclick → onClick
    • {#if} → {&&} or ternary
  4. Update imports:

    • from "annota/svelte" → from "annota/react"