@pic0/spa
v2026.1.12
Published
PicoSPA - progressive enhancer for your MPA, make it feel PicoSPA
Maintainers
Readme
PicoSPA
PicoSPA - progressive enhancer for your MPA, make it feel PicoSPA.
PicoSPA makes Multi-Page Applications (MPAs) feel a bit more like Single-Page Applications (SPAs) — without changing your architecture.
It's a small, framework-agnostic JavaScript library that allows you to:
- Restore scroll positions across navigations
- Reopen
<details>elements after reload - Toggle and restore color schemes
- Add anchors to headings
- Store all state in
sessionStorage - It adds no dependencies, weighs ~2KB minified
Use it with a <script> tag and enhance your site with just a few lines.
💡 Why?
MPAs often lose state (scroll, UI toggles, etc.) between page loads.
SPAs often come with huge frameworks and complexity, size and speed overhead without much gain.
PicoSPA helps you preserve these micro-interactions without rewriting your site.
See how kokoanalytics
uses exactly this same approach.
🚀 Getting Started
Include via a script tag at the end of your page, or at least after the DOM nodes referred to have been rendered.
<script src="https://cdn.jsdelivr.net/npm/@pic0/[email protected]/_dist/picospa.min.js"></script>
<script>
// Restore scroll position of the page, useful e.g. when filtering/sorting data, big forms, comments, threads, ...
picospa.scroll.restore();
// Reopen the <details> on page changes or when coming back to the page.
picospa.details.reopen();
// Restore the color scheme, e.g. light or dark mode.
picospa.colorScheme.restoreLast();
// Add anchors to headings, so you can link to them.
picospa.section.addAnchors();
</script>
<p>Toggle the color scheme.</p>
<button onclick="picospa.colorScheme.toggle();">Toggle Color Scheme</button>Development
Setup
npx playwright installto install the browsers needed for the tests
Run the tests
npm run test:serve(in a console) to start the test server that will be needed for running the playwright testsnpm run test(in another console) to run the playwright tests Why run it in two consoles? I just do it like that, so I can also open and look at test files directly in the browser, e.g.http://localhost:3000/test/section.htmlto see the section tests.npm run test:fastto run the tests only in chromium, which reduces the number of tests and browsers to run, to get faster feedback
