Skip to content

HF-122: Framework integration guides for React, Angular, Vue, Svelte#1653

Open
marcin-kordas-hoc wants to merge 8 commits intodevelopfrom
feature/hf-122-framework-integration-guides
Open

HF-122: Framework integration guides for React, Angular, Vue, Svelte#1653
marcin-kordas-hoc wants to merge 8 commits intodevelopfrom
feature/hf-122-framework-integration-guides

Conversation

@marcin-kordas-hoc
Copy link
Copy Markdown
Collaborator

@marcin-kordas-hoc marcin-kordas-hoc commented Apr 13, 2026

Summary

Expand the four framework integration pages (React, Angular, Vue, Svelte) from one-line redirects into self-contained guides covering idiomatic patterns, lifecycle wiring, TypeScript, SSR caveats, and related next steps.

Design rationale

Why idiomatic patterns, not generic HyperFormula examples

Each guide answers the question specific to its framework: "Where does the HF instance live, how does it clean up, and how do computed values reach the view?" A generic buildFromArray + console.log(getSheetValues) would not justify separate pages — basic-usage.md already covers that.

Framework Key pattern
React useRef for instance, useEffect for init+cleanup, useState for derived values
Angular @Injectable service, inject(DestroyRef) for cleanup, signal() for OnPush compat
Vue markRaw to opt out of Proxy reactivity, ref for derived values, onUnmounted cleanup
Svelte Top-level const for instance, $state rune for reactivity, onDestroy for cleanup

Why TypeScript everywhere

HyperFormula ships .d.ts typings. TS snippets give readers autocomplete for buildFromArray, setCellContents, getSheetValues return types (CellValue[][]), and RawCellContent parameter constraints.

Why licenseKey: 'gpl-v3' in every snippet

Without it, buildFromArray throws a license warning on first run. Previous snippets had // your configuration goes here which hid this.

Why SSR sections (Next.js, Nuxt, SvelteKit)

HyperFormula depends on browser-only APIs. The three most popular meta-frameworks all default to SSR. Without guidance, developers hit a crash on first npm run dev.

VuePress template syntax fix

Stackblitz demo links used ${$page.buildDateURIEncoded} (JS template literal syntax) which VuePress does not interpolate in markdown. Fixed to {{ $page.buildDateURIEncoded }} (Vue template syntax) matching config.js:79 documented intent. Note: docs/guide/custom-functions.md:361 has the same pre-existing issue from PR #1621 — left for a separate fix.

Simulated developer onboarding audits

Each guide was reviewed in 3 rounds by Claude Sonnet sub-agents with distinct developer personas. Round 1 also included OpenAI Codex gpt-5 reviews for React and Angular (provider diversity).

Personas tested

Persona Profile
React A 6yr React, hooks, TS, Next.js 14 App Router, StrictMode-aware
Angular A 5yr Angular 17+, standalone, Signals, DestroyRef, OnPush, NgRx
Vue A 3yr Vue 3 Composition API, TS-first, Nuxt 3, Pinia
Svelte A 2yr Svelte 5 runes, SvelteKit, TS-first
React C (Codex) Mid-level, migrating from vanilla JS HF to React+Vite+TS
Angular C (Codex) Senior Angular, evaluating modern patterns

Round 1 verdict (pre-rewrite): ALL "No, cannot integrate in 10 min"

Critical findings:

  • Svelte: memory leak — no onDestroy / hf.destroy()
  • Angular: stuck in pre-Angular-14 patterns (no Signals, no inject, no DestroyRef, no standalone)
  • All 4: no licenseKey → throws on first run; no TypeScript; no SSR guidance
  • React: StrictMode double-invocation unaddressed; update snippet orphaned

Round 2 verdict (post-rewrite): ALL "Yes, barely — 10-15 min"

Remaining issues found and fixed:

  • Angular: missing ChangeDetectionStrategy import
  • React: no JSX return block
  • Vue: Nuxt SSR snippet missing null-guard; Pinia store missing updateCell
  • Svelte: updateCell not wired in template

Round 3 verdict (final): ALL "Yes, ship-ready"

Provider diversity insight (Claude Sonnet vs Codex gpt-5)

  • Claude: deeper conceptual analysis (Vue Proxy mechanism, StrictMode double-invoke)
  • Codex: more line-level, concrete citations
  • 100% agreement on: modern Angular gap, placeholder problem, SSR gap, TS absence

tsc smoke check

Extracted all 10 code snippets into standalone .ts/.tsx files and ran tsc --noEmit --strict against HyperFormula's own typings with minimal framework stubs.

Result: 0 errors (after fixing unknown → RawCellContent caught by the check).

Snippets tested: react-basic, react-ssr, angular-service, angular-component, angular-rxjs, vue-basic, vue-nuxt, vue-pinia, svelte-basic, svelte-ssr.

Commits

  1. 27b9582a — Initial snippets (earlier work)
  2. e920dcc3 — Simplified snippets and demo-link wording (earlier work)
  3. 88056b72Modernize guides with idiomatic patterns (P0-P2 rewrite)
  4. 9571737f — Add Next steps cross-links
  5. bd84ce9c — Fix VuePress template syntax (${}{{ }})
  6. 87c2f468 — Fix setCellContents type (unknownRawCellContent) — found by tsc smoke

Test plan

  • Render docs locally (npm run docs:dev) and verify all four integration pages
  • Click each Stackblitz demo link — confirm ?v= resolves to HF build date
  • Copy-paste "Basic usage" snippet into scaffolded project per framework
  • Verify Angular component snippet has ChangeDetectionStrategy import
  • Verify Svelte primary snippet warns about SvelteKit SSR before the code block
  • Confirm Vue Nuxt onMounted snippet satisfies strict TS null-checks

Note

Low Risk
Low risk documentation-only change; main risk is incorrect guidance or broken doc templating links.

Overview
Adds a new AGENTS.md with shared AI-assistant guidance for working in the HyperFormula repo (core API, framework lifecycle patterns, common pitfalls, and build/test commands).

Expands the React/Angular/Vue/Svelte integration pages from brief install notes into full, TypeScript-first guides showing idiomatic instance ownership, cleanup, and reactive value bridging, including framework-specific caveats (React StrictMode, Angular DestroyRef/signals, Vue markRaw + troubleshooting, Svelte 5 runes + onDestroy).

Documents SSR-safe patterns for meta-frameworks (Next.js, Nuxt, SvelteKit) and fixes Stackblitz demo URLs to use VuePress interpolation ({{ $page.buildDateURIEncoded }}) so versioned links render correctly.

Reviewed by Cursor Bugbot for commit 2a07790. Bugbot is set up for automated code reviews on this repo. Configure here.

Add idiomatic code examples to React, Angular, Vue, and Svelte
integration pages showing HyperFormula initialization and reading
calculated values. Each guide uses framework-specific patterns
(React hooks, Angular service, Vue ref/markRaw, Svelte reactivity).

Closes HF-122.
Per feedback, snippets now focus on framework-specific integration
patterns (useRef/useEffect, @Injectable, markRaw/ref, Svelte reactivity)
with placeholder comments for data and configuration rather than
concrete values. The Demo section link is reworded from "Explore the
full working example" to "For a more advanced example" to signal that
the Stackblitz demo is a richer, separate project.

Part of HF-122.
Expand React, Angular, Vue and Svelte integration guides to cover
framework-specific concerns that the previous skeleton snippets omitted:

- Convert all snippets to TypeScript with HyperFormula/CellValue imports
- Add licenseKey: 'gpl-v3' to every buildFromArray call
- Inline `npm install hyperformula` install command
- React: runnable JSX with controlled inputs, try/catch around setCellContents,
  React.StrictMode note, Next.js App Router SSR section with 'use client' and
  dynamic import
- Angular: modern standalone component + inject() + DestroyRef + Signals +
  OnPush, RxJS BehaviorSubject variant with AsyncPipe import note, NgZone
  runOutsideAngular section, provider-scope + DestroyRef rationale
- Vue: <script setup lang="ts">, expanded markRaw Proxy explanation and
  shallowRef trap, Nuxt SSR snippet, Pinia store with updateCell action,
  valuesUpdated event hook, inline v-for template
- Svelte: fixes memory leak by adding onDestroy(() => hf.destroy()), Svelte 5
  runes primary example plus Svelte 4 delta, SvelteKit SSR warning banner and
  dedicated onMount section with dynamic import, wired #each template with
  updateCell handler
Point readers from each integration guide to related topics they are
likely to need next: configuration options, basic operations (CRUD),
advanced usage (multi-sheet, named expressions), and custom functions.

Identical section in all four guides so the navigation experience is
consistent when switching between frameworks.
The Stackblitz demo links used \${...} JavaScript template literal syntax,
which is not interpolated by VuePress. VuePress 1 processes markdown as
Vue templates, so the correct syntax for accessing the injected
\$page.buildDateURIEncoded variable is Vue's {{ ... }} interpolation.

config.js line 79 documents the intended syntax explicitly:
  // inject current HF buildDate URI encoded as {{ \$page.buildDateURIEncoded }} variable

Before this fix, the cache-buster query string rendered as a literal
?v=\${\$page.buildDateURIEncoded} in the URL, breaking the cache-busting
behaviour on every Stackblitz demo link.

Note: the same issue exists in docs/guide/custom-functions.md:361 from
an earlier change; that is left for a separate fix.
@qunabu
Copy link
Copy Markdown

qunabu commented Apr 13, 2026

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 13, 2026

Performance comparison of head (2a07790) vs base (736235e)

                                     testName |   base |   head | change
------------------------------------------------------------------------
                                      Sheet A | 489.61 | 488.42 | -0.24%
                                      Sheet B | 155.65 | 158.27 | +1.68%
                                      Sheet T | 138.93 | 141.45 | +1.81%
                                Column ranges | 464.34 | 474.47 | +2.18%
Sheet A:  change value, add/remove row/column |  14.78 |  15.28 | +3.38%
 Sheet B: change value, add/remove row/column | 122.67 | 134.59 | +9.72%
                   Column ranges - add column | 141.82 |  154.2 | +8.73%
                Column ranges - without batch | 425.31 | 450.18 | +5.85%
                        Column ranges - batch | 107.82 | 116.44 | +7.99%

…ntent)

tsc smoke check found that updateCell(value: unknown) does not satisfy
setCellContents which expects RawCellContent. Replace unknown with the
correct type and add missing RawCellContent imports in Angular, Vue and
Svelte guides.
Add framework-agnostic instruction file for AI coding assistants
(Claude Code, GitHub Copilot, Cursor, Gemini CLI). Covers the core
3-operation API surface, framework integration patterns with critical
rules (markRaw, onDestroy, StrictMode, DestroyRef, SSR guards),
key types, common mistakes to prevent, and project structure pointers.
@marcin-kordas-hoc marcin-kordas-hoc marked this pull request as ready for review April 14, 2026 07:18
@marcin-kordas-hoc
Copy link
Copy Markdown
Collaborator Author

Question: Automated testing for framework demos?

During this PR I ran a manual tsc smoke check on all 10 code snippets extracted from the guides — found and fixed a real type bug (unknownRawCellContent).

This raises a broader question: should we have automated tests for the framework demos (both the guide snippets and the Stackblitz demos in hyperformula-demos)?

The risk

Framework demos can silently break when:

  • A framework releases a breaking change (React 19, Angular 18, Svelte 6...)
  • HyperFormula API changes (new required params, renamed types)
  • Bundler updates (Vite, Webpack config changes)
  • Dependency drift (stale lockfile, removed transitive dep)

Currently there are no automated checks — breakage is discovered only when a user clicks a broken Stackblitz link or copy-pastes a non-compiling snippet.

Options considered

Option Where What it catches Setup cost
A: Scheduled CI in demos repo hyperformula-demos Framework breaks ~20 min
B: Cross-repo job in publish.yml HF main repo HF API breaks (before deploy) ~1h
C: Nightly scheduled in HF repo HF main repo Both (builds demos against develop) ~2h

Option A is lowest cost and most immediately useful — a weekly npm ci && npm run build per framework in the demos repo. Zero changes to HF main CI.

Option B catches the other direction (HF breaking demos) and could gate docs deployment.

Related: demo visibility for AI tools

Stackblitz links are invisible to AI coding assistants (Copilot, Cursor, Claude). AI relies solely on the inline snippets in docs/guide/integration-with-*.md. I've added AGENTS.md with framework integration patterns to make these discoverable.

A potential follow-up: vendoring a subset of demo code into docs/examples/ (where 49 examples already live) so AI tools see working examples during code search. This is a separate discussion — noting it here for visibility.

@sequba What do you think — is option A worth setting up? Or is manual verification sufficient for now?

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.19%. Comparing base (736235e) to head (2a07790).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1653   +/-   ##
========================================
  Coverage    97.19%   97.19%           
========================================
  Files          173      173           
  Lines        15013    15013           
  Branches      3209     3209           
========================================
  Hits         14592    14592           
  Misses         421      421           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sequba
Copy link
Copy Markdown
Contributor

sequba commented Apr 14, 2026

@marcin-kordas-hoc I need to be sure the snippets work correctly and align with each framework's best practices, so I want them to be exact code fragments from the linked Stackblitz demos.

You can achieve this by either:

  • updating the code snippets to match the demo code
  • modifying the demos to match the code snippets (but in this case, please make sure that all demos are really well written - this is the code that other devs copy and use in their products, it must be perfect; also we will ask framework experts to review the demos before publication)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants