Home
Softono
j

janosh

Professional software vendor delivering innovative solutions on the Softono platform. Specialized in both open-source and proprietary software development.

Total Products
3

Software by janosh

awesome-sveltekit
Open Source

awesome-sveltekit

<h1 align="center"> <img src="site/static/awesome-sveltekit-banner.svg" alt="Awesome SvelteKit" width="500"> </h1> <h4 align="center"> [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) [![Pull Requests Welcome](https://img.shields.io/badge/Pull%20Requests-welcome-brightgreen.svg?logo=github)](https://github.com/janosh/awesome-sveltekit/pulls) [![Tests](https://github.com/janosh/awesome-sveltekit/actions/workflows/test.yml/badge.svg)](https://github.com/janosh/awesome-sveltekit/actions/workflows/test.yml) [![GH Pages](https://github.com/janosh/awesome-sveltekit/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/janosh/awesome-sveltekit/actions/workflows/gh-pages.yml) </h4> <br> Awesome examples of SvelteKit in the wild. Visit **[janosh.github.io/awesome-sveltekit](https://janosh.github.io/awesome-sveltekit)** to view this list with screenshots plus search and sort functionality (e.g. based on GH stars). ## Sites 1. **[Open WebUI](https://docs.openwebui.com)**&nbsp; [[code](https://github.com/open-webui/open-webui)]&ensp; <a href="https://github.com/open-webui/open-webui/stargazers"> <img src="https://img.shields.io/github/stars/open-webui/open-webui?logo=github" alt="GitHub stars" valign="middle"> </a> User-friendly AI Interface (Supports Ollama, OpenAI API, ...)<br> uses: [highlight.js], [MarkedJS], [KaTeX], [TypeScript], [Tailwind] 1. **[Immich](https://immich.app)**&nbsp; [[code](https://github.com/immich-app/immich)]&ensp; <a href="https://github.com/immich-app/immich/stargazers"> <img src="https://img.shields.io/github/stars/immich-app/immich?logo=github" alt="GitHub stars" valign="middle"> </a> Self-hosted photo and video backup solution directly from your mobile phone.<br> uses: [NestJS], [TypeScript], [Tailwind], [Flutter], [Python] 1. **[Svelte.dev](https://svelte.dev)**&nbsp; [[code](https://github.com/sveltejs/svelte/tree/master/sites/svelte.dev)]&ensp; <a href="https://github.com/sveltejs/svelte/stargazers"> <img src="https://img.shields.io/github/stars/sveltejs/svelte?logo=github" alt="GitHub stars" valign="middle"> </a> Cybernetically enhanced web apps.<br> uses: [CodeMirror], [Mapbox], [Docker] 1. **[Official SvelteKit docs](https://kit.svelte.dev)**&nbsp; [[code](https://github.com/sveltejs/kit/tree/main/documentation/docs)]&ensp; <a href="https://github.com/sveltejs/kit/stargazers"> <img src="https://img.shields.io/github/stars/sveltejs/kit?logo=github" alt="GitHub stars" valign="middle"> </a> The fastest way to build Svelte apps.<br> uses: [Netlify], [PNPM] 1. **[Windmill](https://windmill.dev)**&nbsp; [[code](https://github.com/windmill-labs/windmill/blob/-/frontend)]&ensp; <a href="https://github.com/windmill-labs/windmill/stargazers"> <img src="https://img.shields.io/github/stars/windmill-labs/windmill?logo=github" alt="GitHub stars" valign="middle"> </a> An OSS developer platform to build multi-step automations and internal apps from minimal Python and Typescript scripts.<br> uses: [TypeScript], [Tailwind], [cssnano], [Cypress], [PostCSS], [svelte-highlight], [svelte-markdown] 1. **[VERT](https://vert.sh)**&nbsp; [[code](https://github.com/VERT-sh/VERT)]&ensp; <a href="https://github.com/VERT-sh/VERT/stargazers"> <img src="https://img.shields.io/github/stars/VERT-sh/VERT?logo=github" alt="GitHub stars" valign="middle"> </a> A file converter that converts files client-side while being completely ad-free.<br> uses: [TypeScript], [Tailwind], [Coolify], [WASM], [FFmpeg], [libvips], [Plausible] 1. **[Chat UI](https://huggingface.co/chat)**&nbsp; [[code](https://github.com/huggingface/chat-ui)]&ensp; <a href="https://github.com/huggingface/chat-ui/stargazers"> <img src="https://img.shields.io/github/stars/huggingface/chat-ui?logo=github" alt="GitHub stars" valign="middle"> </a> Powers the HuggingChat app. Making the community&#39;s best AI chat models available to everyone.<br> uses: [Huggingface Inference], [Huggingface Hub], [Tailwind] 1. **[shadcn-svelte](https://shadcn-svelte.com)**&nbsp; [[code](https://github.com/huntabyte/shadcn-svelte/tree/96e8866/docs)]&ensp; <a href="https://github.com/huntabyte/shadcn-svelte/stargazers"> <img src="https://img.shields.io/github/stars/huntabyte/shadcn-svelte?logo=github" alt="GitHub stars" valign="middle"> </a> shadcn/ui, but for Svelte.<br> uses: [TypeScript], [Vercel], [Tailwind], [PNPM], [Changesets], [vitest], [Prism], [MarkedJS] 1. **[mermaid-live-editor](https://mermaid.live)**&nbsp; [[code](https://github.com/mermaid-js/mermaid-live-editor)]&ensp; <a href="https://github.com/mermaid-js/mermaid-live-editor/stargazers"> <img src="https://img.shields.io/github/stars/mermaid-js/mermaid-live-editor?logo=github" alt="GitHub stars" valign="middle"> </a> Edit, live preview and share mermaid charts and diagrams.<br> uses: [TypeScript], [Docker], [Tailwind], [PostCSS], [Cypress], [Husky] 1. **[Skeleton](https://skeleton.dev)**&nbsp; [[code](https://github.com/Brain-Bones/skeleton)]&ensp; <a href="https://github.com/Brain-Bones/skeleton/stargazers"> <img src="https://img.shields.io/github/stars/Brain-Bones/skeleton?logo=github" alt="GitHub stars" valign="middle"> </a> A fully featured web UI toolkit for Svelte + Tailwind. Supports SvelteKit, Vite, and Astro.<br> uses: [Vitest], [PostCSS], [highlight.js], [Tailwind], [Typescript], [jsdom] 1. **[evidence](https://evidence.dev)**&nbsp; [[code](https://github.com/evidence-dev/evidence/blob/-/sites/example-project)]&ensp; <a href="https://github.com/evidence-dev/evidence/stargazers"> <img src="https://img.shields.io/github/stars/evidence-dev/evidence?logo=github" alt="GitHub stars" valign="middle"> </a> Evidence enables analysts to deliver a polished business intelligence system using SQL and markdown.<br> uses: [PNPM], [Changesets], [echarts], [uvu] 1. **[Fireship](https://fireship.io)**&nbsp; [[code](https://github.com/fireship-io/fireship.io)]&ensp; <a href="https://github.com/fireship-io/fireship.io/stargazers"> <img src="https://img.shields.io/github/stars/fireship-io/fireship.io?logo=github" alt="GitHub stars" valign="middle"> </a> The Fireship PRO course platform frontend built with Svelte, Tailwind CSS, Hugo (for static content management), Firebase for Auth and DB, Flamethrower for routing.<br> uses: [Tailwind], [Hugo], [Firebase], [Flamethrower], [Sass], [PostCSS], [Algolia] 1. **[Svelte Material UI](https://sveltematerialui.com)**&nbsp; [[code](https://github.com/hperrin/svelte-material-ui/blob/-/packages/site)]&ensp; <a href="https://github.com/hperrin/svelte-material-ui/stargazers"> <img src="https://img.shields.io/github/stars/hperrin/svelte-material-ui?logo=github" alt="GitHub stars" valign="middle"> </a> Svelte Material UI Components.<br> uses: [MDsveX], [TypeScript], [highlight.js], [remark], [Sass] 1. **[Threlte](https://threlte.xyz)**&nbsp; [[code](https://github.com/threlte/threlte/blob/-/apps/docs)]&ensp; <a href="https://github.com/threlte/threlte/stargazers"> <img src="https://img.shields.io/github/stars/threlte/threlte?logo=github" alt="GitHub stars" valign="middle"> </a> Threlte is a component library for Svelte to build and render three.js scenes declaratively and state-driven in Svelte apps.<br> uses: [TypeScript], [Three.js], [Tailwind], [PostCSS], [Algolia], [Iconify] 1. **[StemRoller](https://stemroller.com)**&nbsp; [[code](https://github.com/stemrollerapp/stemroller)]&ensp; <a href="https://github.com/stemrollerapp/stemroller/stargazers"> <img src="https://img.shields.io/github/stars/stemrollerapp/stemroller?logo=github" alt="GitHub stars" valign="middle"> </a> Isolate vocals, drums, bass, and other instrumental stems from any song<br> uses: [Electron], [Tailwind], [Lodash], [PostCSS], [ytdl-core] 1. **[Flowbite](https://flowbite-svelte.com)**&nbsp; [[code](https://github.com/themesberg/flowbite-svelte)]&ensp; <a href="https://github.com/themesberg/flowbite-svelte/stargazers"> <img src="https://img.shields.io/github/stars/themesberg/flowbite-svelte?logo=github" alt="GitHub stars" valign="middle"> </a> Official Svelte components built for Flowbite and Tailwind CSS. All interactivity handled by Svelte.<br> uses: [PNPM], [TypeScript], [Tailwind], [MDsveX], [Prism], [PostCSS], [Playwright] 1. **[macos-web](https://macos-web.app)**&nbsp; [[code](https://github.com/PuruVJ/macos-web)]&ensp; <a href="https://github.com/PuruVJ/macos-web/stargazers"> <img src="https://img.shields.io/github/stars/PuruVJ/macos-web?logo=github" alt="GitHub stars" valign="middle"> </a> Replicate some of the macOS desktop experience on the web.<br> uses: [TypeScript], [Vercel], [SCSS], [PNPM], [Iconify] 1. **[svelte-realworld](https://github.com/gothinkster/realworld)**&nbsp; [[code](https://github.com/sveltejs/realworld)]&ensp; <a href="https://github.com/sveltejs/realworld/stargazers"> <img src="https://img.shields.io/github/stars/sveltejs/realworld?logo=github" alt="GitHub stars" valign="middle"> </a> SvelteKit implementation of the RealWorld app.<br> uses: [Netlify], [MarkedJS] 1. **[Svelte Headless UI](https://svelte-headlessui.goss.io)**&nbsp; [[code](https://github.com/rgossiaux/svelte-headlessui)]&ensp; <a href="https://github.com/rgossiaux/svelte-headlessui/stargazers"> <img src="https://img.shields.io/github/stars/rgossiaux/svelte-headlessui?logo=github" alt="GitHub stars" valign="middle"> </a> Unofficial Svelte port of Headless UI components.<br> uses: [MDsveX], [TypeScript], [PostCSS], [Tailwind], [cssnano], [Jest], [rehype] 1. **[Svelte Commerce](https://arialshop.com)**&nbsp; [[code](https://github.com/itswadesh/svelte-commerce)]&ensp; <a href="https://github.com/itswadesh/svelte-commerce/stargazers"> <img src="https://img.shields.io/github/stars/itswadesh/svelte-commerce?logo=github" alt="GitHub stars" valign="middle"> </a> Headless, Authentication, Cart &amp; Checkout, TailwindCSS, Server Rendered, Proxy + API Integrated, Animations, Stores, Lazy Loading, Loading Indicators, Carousel, Instant Search, Faceted Filters, Typescript, Open Source, MIT license. 1 command deploy to your own server, 1 click deploy to Netlify/Vercel.<br> uses: [Vercel], [Tailwind], [TypeScript], [svelte-toasts], [PostCSS], [cssnano] 1. **[inlang](https://inlang.com)**&nbsp; [[code](https://github.com/inlang/monorepo)]&ensp; <a href="https://github.com/inlang/monorepo/stargazers"> <img src="https://img.shields.io/github/stars/inlang/monorepo?logo=github" alt="GitHub stars" valign="middle"> </a> Translate software products 2x faster.<br> uses: [TypeScript], [Vercel], [IBM Carbon], [Tailwind], [Supabase] 1. **[Layer Cake](https://layercake.graphics)**&nbsp; [[code](https://github.com/mhkeller/layercake)]&ensp; <a href="https://github.com/mhkeller/layercake/stargazers"> <img src="https://img.shields.io/github/stars/mhkeller/layercake?logo=github" alt="GitHub stars" valign="middle"> </a> Graphics framework for Svelte with colorful demo page. Can generate responsive graphics server-side that work without JavaScript.<br> uses: [D3], [GitHub Pages], [JSDoc], [Mocha], [Underscore] 1. **[editable-website](https://editable.website)**&nbsp; [[code](https://github.com/michael/editable-website)]&ensp; <a href="https://github.com/michael/editable-website/stargazers"> <img src="https://img.shields.io/github/stars/michael/editable-website?logo=github" alt="GitHub stars" valign="middle"> </a> A SvelteKit template for building CMS-free editable websites.<br> uses: [Tailwind], [ProseMirror], [AWS] 1. **[Cryptgeon](https://cryptgeon.org)**&nbsp; [[code](https://github.com/cupcakearmy/cryptgeon/blob/-/packages/frontend)]&ensp; <a href="https://github.com/cupcakearmy/cryptgeon/stargazers"> <img src="https://img.shields.io/github/stars/cupcakearmy/cryptgeon?logo=github" alt="GitHub stars" valign="middle"> </a> A secure, open source notes and file sharing service inspired by PrivNote written in Rust &amp; Svelte.<br> uses: [svelte-intl-precompile], [sanitize-html] 1. **[Dotfyle](https://dotfyle.com)**&nbsp; [[code](https://github.com/codicocodes/dotfyle)]&ensp; <a href="https://github.com/codicocodes/dotfyle/stargazers"> <img src="https://img.shields.io/github/stars/codicocodes/dotfyle?logo=github" alt="GitHub stars" valign="middle"> </a> Discover and share Neovim configurations and plugins.<br> uses: [TypeScript], [PNPM], [tRPC-SvelteKit], [Prisma], [Tailwind], [Octokit] 1. **[svelte-french-toast](https://svelte-french-toast.com)**&nbsp; [[code](https://github.com/kbrgl/svelte-french-toast)]&ensp; <a href="https://github.com/kbrgl/svelte-french-toast/stargazers"> <img src="https://img.shields.io/github/stars/kbrgl/svelte-french-toast?logo=github" alt="GitHub stars" valign="middle"> </a> Svelte port of react-hot-toast, a lightweight, customizable toast notification library.<br> uses: [TypeScript], [Prism], [Tailwind], [PostCSS], [PNPM] 1. **[svelte-put](https://svelte-put.vnphanquang.com)**&nbsp; [[code](https://github.com/vnphanquang/svelte-put)]&ensp; <a href="https://github.com/vnphanquang/svelte-put/stargazers"> <img src="https://img.shields.io/github/stars/vnphanquang/svelte-put?logo=github" alt="GitHub stars" valign="middle"> </a> Useful svelte stuff to put in your projects.<br> uses: [Changesets], [MDsveX], [PostCSS], [PNPM], [Turbo] 1. **[Houdini GraphQL](https://houdinigraphql.com)**&nbsp; [[code](https://github.com/HoudiniGraphQL/houdini)]&ensp; <a href="https://github.com/HoudiniGraphQL/houdini/stargazers"> <img src="https://img.shields.io/github/stars/HoudiniGraphQL/houdini?logo=github" alt="GitHub stars" valign="middle"> </a> Documentation site for Houdini.<br> uses: [PNPM], [MDsveX], [Husky], [highlight.js] 1. **[tRPC-SvelteKit](https://icflorescu.github.io/trpc-sveltekit)**&nbsp; [[code](https://github.com/icflorescu/trpc-sveltekit)]&ensp; <a href="https://github.com/icflorescu/trpc-sveltekit/stargazers"> <img src="https://img.shields.io/github/stars/icflorescu/trpc-sveltekit?logo=github" alt="GitHub stars" valign="middle"> </a> End-to-end type-safe APIs for your SvelteKit applications.<br> uses: [TypeScript], [tRPC] 1. **[swyxkit](https://swyxkit.netlify.app)**&nbsp; [[code](https://github.com/sw-yx/swyxkit)]&ensp; <a href="https://github.com/sw-yx/swyxkit/stargazers"> <img src="https://img.shields.io/github/stars/sw-yx/swyxkit?logo=github" alt="GitHub stars" valign="middle"> </a> An opinionated blog starter for SvelteKit + Tailwind + Netlify. Refreshed for 2022!<br> uses: [Tailwind], [Netlify] 1. **[Urara](https://urara-demo.netlify.app)**&nbsp; [[code](https://github.com/importantimport/urara)]&ensp; <a href="https://github.com/importantimport/urara/stargazers"> <img src="https://img.shields.io/github/stars/importantimport/urara?logo=github" alt="GitHub stars" valign="middle"> </a> Sweet &amp; Powerful SvelteKit Blog Template.<br> uses: [MDsveX], [PostCSS], [Tailwind], [DaisyUI], [TypeScript], [PNPM] 1. **[SvelteKit static blog starter](https://sveltekit-static-starter.netlify.app)**&nbsp; [[code](https://github.com/josh-collinsworth/sveltekit-blog-starter)]&ensp; <a href="https://github.com/josh-collinsworth/sveltekit-blog-starter/stargazers"> <img src="https://img.shields.io/github/stars/josh-collinsworth/sveltekit-blog-starter?logo=github" alt="GitHub stars" valign="middle"> </a> A pre-configured SvelteKit static blog starter, with Sass, Markdown, MDSvex, Rehype and background preloading.<br> uses: [Netlify], [MDsveX], [Sass], [Husky] 1. **[Joy of Code](https://joyofcode.xyz)**&nbsp; [[code](https://github.com/mattcroat/joy-of-code)]&ensp; <a href="https://github.com/mattcroat/joy-of-code/stargazers"> <img src="https://img.shields.io/github/stars/mattcroat/joy-of-code?logo=github" alt="GitHub stars" valign="middle"> </a> 🌸 Joy of Code is a digital garden growing curious minds.<br> uses: [GitHub API], [Monaco], [Playwright], [Google Analytics], [Supabase], [Vercel], [PNPM], [Sass], [TypeScript], [remark], [rehype] 1. **[QWER](https://svelte-qwer.vercel.app)**&nbsp; [[code](https://github.com/kwchang0831/svelte-QWER)]&ensp; <a href="https://github.com/kwchang0831/svelte-QWER/stargazers"> <img src="https://img.shields.io/github/stars/kwchang0831/svelte-QWER?logo=github" alt="GitHub stars" valign="middle"> </a> βœ’οΈŽ Simply Awesome Blog Starter built with SvelteKit and ❀<br> uses: [UnoCSS], [TypeScript], [MarkedJS], [PNPM], [Vercel] 1. **[Files](https://files.community)**&nbsp; [[code](https://github.com/files-community/website)]&ensp; <a href="https://github.com/files-community/website/stargazers"> <img src="https://img.shields.io/github/stars/files-community/website?logo=github" alt="GitHub stars" valign="middle"> </a> 3rd Party File Manager for Windows.<br> uses: [PNPM], [TypeScript], [SCSS], [Vercel] 1. **[Saga Reader](https://aiqino.netlify.app)**&nbsp; [[code](https://github.com/sopaco/saga-reader)]&ensp; <a href="https://github.com/sopaco/saga-reader/stargazers"> <img src="https://img.shields.io/github/stars/sopaco/saga-reader?logo=github" alt="GitHub stars" valign="middle"> </a> Blazing-fast and extremely lightweight AI-powered internet reader. Your AI-driven think tank assistant built with Rust, Tauri and Svelte.<br> uses: [Skeleton], [Rust], [Tauri], [Netlify] 1. **[Svelte Society](https://sveltesociety.dev)**&nbsp; [[code](https://github.com/svelte-society/sveltesociety.dev)]&ensp; <a href="https://github.com/svelte-society/sveltesociety.dev/stargazers"> <img src="https://img.shields.io/github/stars/svelte-society/sveltesociety.dev?logo=github" alt="GitHub stars" valign="middle"> </a> Global network of Svelte fans striving to promote Svelte and its ecosystem.<br> uses: [TypeScript], [Gitpod] 1. **[SvelteLab](https://sveltelab.dev)**&nbsp; [[code](https://github.com/sveltelab/sveltelab)]&ensp; <a href="https://github.com/sveltelab/sveltelab/stargazers"> <img src="https://img.shields.io/github/stars/sveltelab/sveltelab?logo=github" alt="GitHub stars" valign="middle"> </a> Supercharged REPL for Svelte (think StackBlitz specialized for Svelte)<br> uses: [Playwright], [vitest], [Iconify], [MarkedJS], [TypeScript], [PNPM], [Pocketbase], [Vercel], [Tailwind] 1. **[Scientific Diagrams](https://janosh.github.io/diagrams)**&nbsp; [[code](https://github.com/janosh/diagrams)]&ensp; <a href="https://github.com/janosh/diagrams/stargazers"> <img src="https://img.shields.io/github/stars/janosh/diagrams?logo=github" alt="GitHub stars" valign="middle"> </a> 100+ MIT-licensed scientific diagrams created with CeTZ (Typst) and/or TikZ (LaTeX). Mostly about physics, chemistry, and machine learning.<br> uses: [TypeScript], [svelte-multiselect], [pre-commit], [PNPM], [svelte-enhanced-img] 1. **[Watch This](https://github.com/StephDietz/watch-this/issues/28)**&nbsp; [[code](https://github.com/StephDietz/watch-this)]&ensp; <a href="https://github.com/StephDietz/watch-this/stargazers"> <img src="https://img.shields.io/github/stars/StephDietz/watch-this?logo=github" alt="GitHub stars" valign="middle"> </a> Uses OpenAI GPT-3 API and streaming Vercel edge functions to generate cinema recommendations based on user input.<br> uses: [TypeScript], [Vercel], [Tailwind] 1. **[neovim craft](https://neovimcraft.com)**&nbsp; [[code](https://github.com/neurosnap/neovimcraft)]&ensp; <a href="https://github.com/neurosnap/neovimcraft/stargazers"> <img src="https://img.shields.io/github/stars/neurosnap/neovimcraft?logo=github" alt="GitHub stars" valign="middle"> </a> Curated list of neovim plugins.<br> uses: [TypeScript], [Husky] 1. **[Svelte MultiSelect](https://janosh.github.io/svelte-multiselect)**&nbsp; [[code](https://github.com/janosh/svelte-multiselect)]&ensp; <a href="https://github.com/janosh/svelte-multiselect/stargazers"> <img src="https://img.shields.io/github/stars/janosh/svelte-multiselect?logo=github" alt="GitHub stars" valign="middle"> </a> Keyboard-friendly, accessible and highly customizable multi-select component.<br> uses: [Vitest], [Playwright], [Typescript], [PNPM], [pre-commit], [rehype], [jsdom], [GitHub Pages], [mdsvexamples] 1. **[Modern Fluid Typography Editor](https://modern-fluid-typography.vercel.app)**&nbsp; [[code](https://github.com/codeAdrian/modern-fluid-typography-editor)]&ensp; <a href="https://github.com/codeAdrian/modern-fluid-typography-editor/stargazers"> <img src="https://img.shields.io/github/stars/codeAdrian/modern-fluid-typography-editor?logo=github" alt="GitHub stars" valign="middle"> </a> Easily create and fine-tune fluid typography values with Modern CSS <code>clamp()</code>.<br> uses: [TypeScript], [PostCSS], [Chart.js], [cssnano] 1. **[Matt Fantinel](https://fantinel.dev)**&nbsp; [[code](https://github.com/matfantinel/matfantinel.github.io)]&ensp; <a href="https://github.com/matfantinel/matfantinel.github.io/stargazers"> <img src="https://img.shields.io/github/stars/matfantinel/matfantinel.github.io?logo=github" alt="GitHub stars" valign="middle"> </a> Personal website and blog of Matt Fantinel, web developer.<br> uses: [MDsveX], [SCSS], [Iconoir], [Plausible] 1. **[MatterViz](https://janosh.github.io/matterviz)**&nbsp; [[code](https://github.com/janosh/matterviz)]&ensp; <a href="https://github.com/janosh/matterviz/stargazers"> <img src="https://img.shields.io/github/stars/janosh/matterviz?logo=github" alt="GitHub stars" valign="middle"> </a> Interactive visualizations for materials science: periodic tables, 3d crystal structures (Molecules coming soon), Bohr atoms, nuclei, heatmaps, scatter plots.<br> uses: [TypeScript], [pre-commit], [D3], [svelte-multiselect], [Vitest], [Playwright], [PNPM], [jsdom], [GitHub Pages] 1. **[Significa.co](https://significa.co)**&nbsp; [[code](https://github.com/significa/significa.co)]&ensp; <a href="https://github.com/significa/significa.co/stargazers"> <img src="https://img.shields.io/github/stars/significa/significa.co?logo=github" alt="GitHub stars" valign="middle"> </a> Product Design and Development agency website, built with Sveltekit.<br> uses: [TypeScript], [Vercel], [Tailwind], [AWS], [Dynamodb], [Notion], [Storyblock], [Matter.js], [Plausible] 1. **[ASM Editor](https://asm-editor.specy.app)**&nbsp; [[code](https://github.com/Specy/asm-editor)]&ensp; <a href="https://github.com/Specy/asm-editor/stargazers"> <img src="https://img.shields.io/github/stars/Specy/asm-editor?logo=github" alt="GitHub stars" valign="middle"> </a> A modern webapp to write, run and learn M68K assembly code.<br> uses: [TypeScript], [Sass], [Monaco], [WASM] 1. **[Svelte Intl Precompile](https://github.com/cibernox/svelte-intl-precompile)**&nbsp; [[code](https://github.com/cibernox/svelte-intl-precompile)]&ensp; <a href="https://github.com/cibernox/svelte-intl-precompile/stargazers"> <img src="https://img.shields.io/github/stars/cibernox/svelte-intl-precompile?logo=github" alt="GitHub stars" valign="middle"> </a> I18n library for Svelte that analyzes your keys at build time for maximum performance and minimal footprint. Built as a SvelteKit plugin so good to use as a reference if you want to build one yourself.<br> uses: [JS-Yaml], [JSON5] 1. **[SvelteKit Embed](https://sveltekit-embed.vercel.app)**&nbsp; [[code](https://github.com/spences10/sveltekit-embed)]&ensp; <a href="https://github.com/spences10/sveltekit-embed/stargazers"> <img src="https://img.shields.io/github/stars/spences10/sveltekit-embed?logo=github" alt="GitHub stars" valign="middle"> </a> SvelteKit embed components for YouTube, Vimeo, Twitter, Spotify, SoundCloud, StackBlitz, CodePen, AnchorFM, Simple Cast and more.<br> uses: [TypeScript], [PNPM], [Vercel], [MDsveX], [Tailwind], [PostCSS], [Husky], [Playwright], [DaisyUI] 1. **[SvelteKit on Edge](https://sveltekit-on-the-edge.vercel.app)**&nbsp; [[code](https://github.com/Rich-Harris/sveltekit-on-the-edge)]&ensp; <a href="https://github.com/Rich-Harris/sveltekit-on-the-edge/stargazers"> <img src="https://img.shields.io/github/stars/Rich-Harris/sveltekit-on-the-edge?logo=github" alt="GitHub stars" valign="middle"> </a> SvelteKit, running on the edge. In this case, Vercel&#39;s edge network. See <a href="https://twitter.com/leeerob/status/1517627769924034565">https://twitter.com/leeerob/status/1517627769924034565</a>.<br> uses: [PNPM], [Vercel] 1. **[Pixel Art Together](https://pixelart.liveblocks.app)**&nbsp; [[code](https://github.com/liveblocks/pixel-art-together)]&ensp; <a href="https://github.com/liveblocks/pixel-art-together/stargazers"> <img src="https://img.shields.io/github/stars/liveblocks/pixel-art-together?logo=github" alt="GitHub stars" valign="middle"> </a> A multiplayer pixel art editor powered by Liveblocks.<br> uses: [TypeScript], [Liveblocks], [Tailwind], [PostCSS], [panzoom] 1. **[Hexapipes](https://hexapipes.vercel.app)**&nbsp; [[code](https://github.com/gereleth/hexapipes)]&ensp; <a href="https://github.com/gereleth/hexapipes/stargazers"> <img src="https://img.shields.io/github/stars/gereleth/hexapipes?logo=github" alt="GitHub stars" valign="middle"> </a> Browser game where the goal is to correctly line up pipes placed on hexagonal puzzle pieces.<br> uses: [Vercel] 1. **[svelte-command-palette](https://svelte-command-palette.vercel.app)**&nbsp; [[code](https://github.com/rohitpotato/svelte-command-palette)]&ensp; <a href="https://github.com/rohitpotato/svelte-command-palette/stargazers"> <img src="https://img.shields.io/github/stars/rohitpotato/svelte-command-palette?logo=github" alt="GitHub stars" valign="middle"> </a> Dead simple command palette with fuzzy search.<br> uses: [TypeScript], [Playwright], [PostCSS], [Tailwind], [Release It], [Vercel] 1. **[sveltekit-mdsvex-blog](https://sveltekit-mdsvex-blog.netlify.app)**&nbsp; [[code](https://github.com/mvasigh/sveltekit-mdsvex-blog)]&ensp; <a href="https://github.com/mvasigh/sveltekit-mdsvex-blog/stargazers"> <img src="https://img.shields.io/github/stars/mvasigh/sveltekit-mdsvex-blog?logo=github" alt="GitHub stars" valign="middle"> </a> A minimalist blog template built with SvelteKit and MDsveX.<br> uses: [TypeScript], [MDsveX], [Rehype], [Remark], [PNPM], [Vitest], [Playwright] 1. **[Statue](https://statue.dev)**&nbsp; [[code](https://github.com/accretional/statue)]&ensp; <a href="https://github.com/accretional/statue/stargazers"> <img src="https://img.shields.io/github/stars/accretional/statue?logo=github" alt="GitHub stars" valign="middle"> </a> A Svelte-based static site generator with built in component library.<br> uses: [GitHub Pages], [CloudFlare Pages], [Netlify] 1. **[Intl Explorer](https://intl-explorer.com)**&nbsp; [[code](https://github.com/jesperorb/intl-explorer)]&ensp; <a href="https://github.com/jesperorb/intl-explorer/stargazers"> <img src="https://img.shields.io/github/stars/jesperorb/intl-explorer?logo=github" alt="GitHub stars" valign="middle"> </a> A tool for experimenting and trying out the ECMAScript Internationalization API.<br> uses: [TypeScript], [PNPM], [Playwright], [Vercel], [svelte-highlight], [Husky], [commitlint] 1. **[Auth starter app](https://passlock.dev)**&nbsp; [[code](https://github.com/passlock-dev/passlock)]&ensp; <a href="https://github.com/passlock-dev/passlock/stargazers"> <img src="https://img.shields.io/github/stars/passlock-dev/passlock?logo=github" alt="GitHub stars" valign="middle"> </a> SvelteKit template featuring Passkeys, Social Sign in and more.<br> uses: [passlock], [tailwind], [superforms], [lucia] 1. **[Svead](https://svead.pages.dev)**&nbsp; [[code](https://github.com/spences10/svead)]&ensp; <a href="https://github.com/spences10/svead/stargazers"> <img src="https://img.shields.io/github/stars/spences10/svead?logo=github" alt="GitHub stars" valign="middle"> </a> Svead 🍺, a component that allows you to set head meta information, canonical, title, Twitter and Facebook Open Graph tags, and schema.org data.<br> uses: [TypeScript], [PNPM], [Cloudflare Pages], [MDsveX], [Tailwind], [PostCSS], [DaisyUI] 1. **[Paper Trader Game](https://paper-trader.davjhan.com)**&nbsp; [[code](https://github.com/davjhan/paper-trader-game)]&ensp; <a href="https://github.com/davjhan/paper-trader-game/stargazers"> <img src="https://img.shields.io/github/stars/davjhan/paper-trader-game?logo=github" alt="GitHub stars" valign="middle"> </a> A simple web game where you are given 45 seconds and $100 to make as much money as you can trading a fake stock.<br> uses: [Tailwind], [Netlify], [Chart.js], [Plausible] 1. **[markushatvan.com](https://markushatvan.com)** Blog posts with code snippets, contact form with Svelte Forms Lib, RSS and sitemap.<br> uses: [Tailwind], [MDsveX], [Svelte Forms Lib] 1. **[The Pudding](https://pudding.cool)**&nbsp; [[code](https://github.com/the-pudding/website)]&ensp; <a href="https://github.com/the-pudding/website/stargazers"> <img src="https://img.shields.io/github/stars/the-pudding/website?logo=github" alt="GitHub stars" valign="middle"> </a> Digital publication with emphasis on data viz.<br> uses: [D3], [PostCSS], [Lodash], [PNPM] 1. **[connorrothschild.com](https://connorrothschild.com)**&nbsp; [[code](https://github.com/connorrothschild/v4)]&ensp; <a href="https://github.com/connorrothschild/v4/stargazers"> <img src="https://img.shields.io/github/stars/connorrothschild/v4?logo=github" alt="GitHub stars" valign="middle"> </a> Creative, content-based portfolio site of Connor Rothschild.<br> uses: [MDsveX], [GSAP], [Netlify] 1. **[macOS-Themed Portfolio](https://macosportfolio.netlify.app)**&nbsp; [[code](https://github.com/ansxuman/macOS-Themed-Portfolio)]&ensp; <a href="https://github.com/ansxuman/macOS-Themed-Portfolio/stargazers"> <img src="https://img.shields.io/github/stars/ansxuman/macOS-Themed-Portfolio?logo=github" alt="GitHub stars" valign="middle"> </a> An interactive portfolio website inspired by the macOS interface.<br> uses: [TypeScript], [Tailwind], [PM2], [Cloudflare], [Netlify], [Nginx] 1. **[Guess The Year](https://github.com/davjhan/guess-the-year-game)**&nbsp; [[code](https://github.com/davjhan/guess-the-year-game)]&ensp; <a href="https://github.com/davjhan/guess-the-year-game/stargazers"> <img src="https://img.shields.io/github/stars/davjhan/guess-the-year-game?logo=github" alt="GitHub stars" valign="middle"> </a> Round-based browser game where you guess the year in which famous event happened. Answers range between 1900-2021. You start with 100 points. The more your guess is off, the more points you loose.<br> uses: [Tailwind], [Netlify] 1. **[Multi-Monitor Calculator](https://multimonitorcalculator.com)**&nbsp; [[code](https://github.com/KevinVandy/multi-monitor_calculator)]&ensp; <a href="https://github.com/KevinVandy/multi-monitor_calculator/stargazers"> <img src="https://img.shields.io/github/stars/KevinVandy/multi-monitor_calculator?logo=github" alt="GitHub stars" valign="middle"> </a> A tool for planning your multi-monitor setup.<br> uses: [TypeScript], [SMUI], [Sass] 1. **[barnsworthburning](https://barnsworthburning.net)**&nbsp; [[code](https://github.com/Aias/barnsworthburning)]&ensp; <a href="https://github.com/Aias/barnsworthburning/stargazers"> <img src="https://img.shields.io/github/stars/Aias/barnsworthburning?logo=github" alt="GitHub stars" valign="middle"> </a> An experimental commonplace book / digital garden with a richly interconnected set of links, notes, and ideas.<br> uses: [TypeScript], [Airtable], [Radix], [MarkedJS], [Cloudflare Pages] 1. **[ConcertMash](https://concertmash.com)**&nbsp; [[code](https://github.com/mcmxcdev/ConcertMash)]&ensp; <a href="https://github.com/mcmxcdev/ConcertMash/stargazers"> <img src="https://img.shields.io/github/stars/mcmxcdev/ConcertMash?logo=github" alt="GitHub stars" valign="middle"> </a> Easily generate a playlist for your upcoming concerts based on selected artists!<br> uses: [TypeScript], [Tailwind], [Spotify Web API], [Filepond], [PNPM], [Netlify] 1. **[Team Health Check](https://team-health-check-coral.vercel.app)**&nbsp; [[code](https://github.com/codehub-kirans/team-health-check)]&ensp; <a href="https://github.com/codehub-kirans/team-health-check/stargazers"> <img src="https://img.shields.io/github/stars/codehub-kirans/team-health-check?logo=github" alt="GitHub stars" valign="middle"> </a> A tool to visualize historical agile scrum team performance based on behavior anchors.<br> uses: [PicoCSS], [Pocketbase], [Vercel] 1. **[digital criticism](https://critique-digitale.ch)**&nbsp; [[code](https://github.com/critique-digitale/critique-digitale.ch)]&ensp; <a href="https://github.com/critique-digitale/critique-digitale.ch/stargazers"> <img src="https://img.shields.io/github/stars/critique-digitale/critique-digitale.ch?logo=github" alt="GitHub stars" valign="middle"> </a> Scholarly conference in the digital humanities.<br> uses: [MDsveX], [MVP.css], [Cloudflare] 1. **[Svelvet](https://svelvet.io)**&nbsp; [[code](https://github.com/oslabs-beta/Svelvet)]&ensp; <a href="https://github.com/oslabs-beta/Svelvet/stargazers"> <img src="https://img.shields.io/github/stars/oslabs-beta/Svelvet?logo=github" alt="GitHub stars" valign="middle"> </a> A lightweight Svelte component library for building interactive node-based flow diagrams.<br> uses: [Playwright], [D3], [Testing Library], [Tailwind], [PostCSS], [Vitest] 1. **[Flayks](https://flayks.com)** Portfolio of FΓ©lix PΓ©ault, Digital Designer and Art Director. Sanity.io [<a href="https://sanity.io/blog/felix-peault-community-interview">interview</a>], [<a href="https://sanity.io/projects/flayks-portfolio-2021">feature</a>].<br> uses: [Sanity], [anime.js], [Vercel], [TypeScript], [SCSS], [PostCSS] 1. **[Level Up Tutorials](https://leveluptutorials.com)** Video tutorials for web developers and designers.<br> uses: [TypeScript], [Google Tag Manager] 1. **[JSchallenger](https://jschallenger.com)** Free Javascript challenges. Learn Javascript online by solving coding exercises.<br> uses: [Tailwind], [DynamoDB], [AWS] 1. **[cybernetic.dev](https://cybernetic.dev)** Data-centric UI experiments<br> uses: [Three.js], [Cytoscape.js], [Vercel] 1. **[Houses of World](https://housesof.world)** A travel, photography and design project showcasing charismatic houses around the world.<br> uses: [Typescript], [SCSS], [PostCSS], [Motion One], [OGL], [WebGL], [Directus], [Swell Commerce], [Vercel] [airtable]: https://airtable.com [algolia]: https://algolia.com [anime.js]: https://animejs.com [aws]: https://aws.amazon.com [changesets]: https://github.com/changesets/changesets [chart.js]: https://chartjs.org [cloudflare pages]: https://pages.cloudflare.com [cloudflare]: https://cloudflare.com [codemirror]: https://codemirror.net [commitlint]: https://github.com/conventional-changelog/commitlint [coolify]: https://coolify.io [cssnano]: https://cssnano.github.io/cssnano [cypress]: https://cypress.io [cytoscape.js]: https://js.cytoscape.org [d3]: https://d3js.org [daisyui]: https://daisyui.com [directus]: https://directus.io [docker]: https://docker.com [dynamodb]: https://aws.amazon.com/dynamodb [echarts]: https://github.com/apache/echarts [electron]: https://electronjs.org [ffmpeg]: https://ffmpeg.org [filepond]: https://pqina.nl/filepond [firebase]: https://firebase.google.com [flamethrower]: https://github.com/fireship-io/flamethrower [flutter]: https://flutter.dev [github api]: https://docs.github.com/rest [github pages]: https://pages.github.com [gitpod]: https://gitpod.io [google analytics]: https://analytics.google.com [google tag manager]: https://tagmanager.google.com [gsap]: https://greensock.com/gsap [highlight.js]: https://highlightjs.org [huggingface hub]: https://github.com/huggingface/huggingface_hub [huggingface inference]: https://github.com/huggingface/text-generation-inference [hugo]: https://gohugo.io [husky]: https://github.com/typicode/husky [ibm carbon]: https://carbondesignsystem.com [iconify]: https://iconify.design [iconoir]: https://iconoir.com [jest]: https://jestjs.io [js-yaml]: https://github.com/nodeca/js-yaml [jsdoc]: https://jsdoc.app [jsdom]: https://github.com/jsdom/jsdom [json5]: https://github.com/json5/json5 [katex]: https://github.com/KaTeX/KaTeX [libvips]: https://libvips.org [liveblocks]: https://liveblocks.io [lodash]: https://lodash.com [lucia]: https://github.com/lucia-auth/lucia [mapbox]: https://mapbox.com [markedjs]: https://marked.js.org [matter.js]: https://brm.io/matter-js [mdsvex]: https://github.com/pngwn/MDsveX [mdsvexamples]: https://github.com/mattjennings/mdsvexamples [mocha]: https://mochajs.org [monaco]: https://microsoft.github.io/monaco-editor [motion one]: https://motion.dev [mvp.css]: https://github.com/andybrewer/mvp [nestjs]: https://nestjs.com [netlify]: https://netlify.com [nginx]: https://nginx.org [notion]: https://notion.so [octokit]: https://github.com/octokit/octokit.js [ogl]: https://github.com/oframe/ogl [panzoom]: https://github.com/timmywil/panzoom [passlock]: https://github.com/passlock-dev/passkeys [picocss]: https://picocss.com [plausible]: https://plausible.io [playwright]: https://playwright.dev [pm2]: https://pm2.io [pnpm]: https://pnpm.io [pocketbase]: https://pocketbase.io [postcss]: https://postcss.org [pre-commit]: https://pre-commit.com [prism]: https://prismjs.com [prisma]: https://prisma.io [prosemirror]: https://prosemirror.net [python]: https://python.org [radix]: https://radix-ui.com [rehype]: https://github.com/rehypejs/rehype [release it]: https://github.com/release-it/release-it [remark]: https://github.com/remarkjs/remark [rust]: https://rust-lang.org [sanitize-html]: https://github.com/apostrophecms/sanitize-html [sanity]: https://sanity.io [sass]: https://sass-lang.com [scss]: https://sass-lang.com/documentation/syntax [skeleton]: https://skeleton.dev [smui]: https://sveltematerialui.com [spotify web api]: https://github.com/JMPerez/spotify-web-api-js [storyblock]: https://storyblok.com [supabase]: https://supabase.com [superforms]: https://github.com/ciscoheat/sveltekit-superforms [svelte forms lib]: https://github.com/tjinauyeung/svelte-forms-lib [svelte-enhanced-img]: https://svelte.dev/docs/kit/images#sveltejs-enhanced-img [svelte-highlight]: https://github.com/metonym/svelte-highlight [svelte-intl-precompile]: https://github.com/cibernox/svelte-intl-precompile [svelte-markdown]: https://github.com/pablo-abc/svelte-markdown [svelte-multiselect]: https://github.com/janosh/svelte-multiselect [svelte-toasts]: https://github.com/mzohaibqc/svelte-toasts [swell commerce]: https://swell.is [tailwind]: https://tailwindcss.com [tauri]: https://tauri.app [testing library]: https://testing-library.com [three.js]: https://threejs.org [trpc-sveltekit]: https://github.com/icflorescu/trpc-sveltekit [trpc]: https://trpc.io [turbo]: https://github.com/vercel/turbo [typescript]: https://typescriptlang.org [underscore]: https://underscorejs.org [unocss]: https://github.com/unocss/unocss [uvu]: https://github.com/lukeed/uvu [vercel]: https://vercel.com [vitest]: https://vitest.dev [wasm]: https://webassembly.org [webgl]: https://developer.mozilla.org/docs/Web/API/WebGL_API [ytdl-core]: https://github.com/fent/node-ytdl-core ## πŸŽ‰ Suggestions Welcome Want to add an open-source project to this list? [PRs welcome](https://github.com/janosh/awesome-sveltekit/edit/main/sites.yml)! This collection is a community effort intended as a learning resource for Svelte devs. Entry requirements: 1. **open source**: While a site with private code can give design and feature ideas, there's little educational value if you can't inspect how it was made. 1. **novel**: Not just another blog or todo app. Ideally, some application or technology not already covered in this collection. 1. **popular**: At least 50 stars on GitHub or reasonable expectation to reach that number soon. These requirements arose over time so not all existing entries satisfy them. There can also be tradeoffs. For example, if novelty is very high, popularity can be lower. If you're unsure, please [open a discussion](https://github.com/janosh/awesome-sveltekit/discussions) first. A good place to discover influential Svelte projects (not necessarily SvelteKit) is [GitHub Trending](https://github.com/trending/svelte?since=monthly). If anything on that list stands out to you but is missing here, please add it!

Personal Dashboards
1.3K Github Stars
svelte-multiselect
Open Source

svelte-multiselect

<h1 align="center"> <img src="https://raw.githubusercontent.com/janosh/svelte-multiselect/main/static/favicon.svg" alt="Svelte MultiSelect" height="60" width="60"> <br class="hide-in-docs"> Svelte MultiSelect </h1> <h4 align="center"> [![Tests](https://github.com/janosh/svelte-multiselect/actions/workflows/test.yml/badge.svg)](https://github.com/janosh/svelte-multiselect/actions/workflows/test.yml) [![GitHub Pages](https://github.com/janosh/svelte-multiselect/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/janosh/svelte-multiselect/actions/workflows/gh-pages.yml) [![NPM version](https://img.shields.io/npm/v/svelte-multiselect?logo=NPM&color=purple)](https://npmjs.com/package/svelte-multiselect) [![Needs Svelte version](https://img.shields.io/npm/dependency-version/svelte-multiselect/peer/svelte?color=teal&logo=Svelte&label=Svelte)](https://github.com/sveltejs/svelte/blob/master/packages/svelte/CHANGELOG.md) [![Playground](https://img.shields.io/badge/Svelte-Playground-blue?label=Try%20it!)](https://svelte.dev/playground/a5a14b8f15d64cb083b567292480db05) [![Open in StackBlitz](https://img.shields.io/badge/Open%20in-StackBlitz-darkblue?logo=stackblitz)](https://stackblitz.com/github/janosh/svelte-multiselect) </h4> <p align="center"><strong> Keyboard-friendly, accessible and highly customizable multi-select component. <a class="hide-in-docs" href="https://janosh.github.io/svelte-multiselect">View the docs</a> </strong></p> <slot name="examples" /> ## πŸ’‘ &thinsp; Features - **Bindable:** `bind:selected` gives you an array of the currently selected options. Thanks to Svelte's 2-way binding, it can also control the component state externally through assignment `selected = ['foo', 42]`. - **Keyboard friendly** for mouse-less form completion - **No run-time deps:** needs only Svelte as dev dependency - **Dropdowns:** scrollable lists for large numbers of options - **Searchable:** start typing to filter options - **Tagging:** selected options are listed as tags within the input - **Single / multiple select:** pass `maxSelect={1, 2, 3, ...}` prop to restrict the number of selectable options - **Configurable:** see props ## πŸ§ͺ &thinsp; Coverage | Statements | Branches | Lines | | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------ | | ![Statements](https://img.shields.io/badge/statements-93%25-yellow.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-87%25-yellow.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-94%25-yellow.svg?style=flat) | ## πŸ”¨ &thinsp; Installation ```sh npm install --dev svelte-multiselect ``` ## πŸ“™ &thinsp; Usage ```svelte <script> import MultiSelect from 'svelte-multiselect' const ui_libs = [`Svelte`, `React`, `Vue`, `Angular`, `...`] let selected = $state([]) </script> Favorite Frontend Tools? <code>selected = {JSON.stringify(selected)}</code> <MultiSelect bind:selected options={ui_libs} /> ``` ## 🧠 &thinsp; Mental Model | Prop | Purpose | Value | | --------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------- | | `options` | What users can choose from | Array of strings, numbers, or objects with `label` property | | `bind:selected` | Which options users have chosen | Always an array: `[]`, `['Apple']` or `['Apple', 'Banana']` | | `bind:value` | Single-select convenience for the user-selected option | Single item: `'Apple'` (or `null`) if `maxSelect={1}`, otherwise same as `selected` | ### Common Patterns ```svelte <!-- Multi-select --> <MultiSelect bind:selected options={['A', 'B', 'C']} /> <!-- Single-select --> <MultiSelect bind:value options={colors} maxSelect={1} /> <!-- Object options (need 'label' property, can have arbitrary other keys, some like `value`, `disabled`, `preselected`, `style` have special meaning, see type ObjectOption) --> <MultiSelect bind:selected options={[ { label: 'Red', value: '#ff0000' }, { label: 'Blue', value: '#0000ff' }, ]} /> ``` ### Troubleshooting - **Object options not working?** β†’ Add `label` property - **Dropdown not showing?** β†’ Check you have `options` and not `disabled={true}` - **Want single item not array?** β†’ Use `bind:value` with `maxSelect={1}` - **Types confusing?** β†’ Component auto-infers type of `selected` and `value` from your `options` array ## πŸ”£ &thinsp; Props Complete reference of all props. Props are organized by importance - **Essential Props** are what you'll use most often. > **πŸ’‘ Tip:** The `Option` type is automatically inferred from your `options` array, or you can import it: `import { type Option } from 'svelte-multiselect'` ### Essential Props These are the core props you'll use in most cases: 1. ```ts options?: Option[] // required unless loadOptions is provided ``` Array of strings, numbers, or objects that users can select from. Objects must have a `label` property that will be displayed in the dropdown. Omit this when using `loadOptions` as the source of dynamic options. ```svelte <!-- Simple options --> <MultiSelect options={['Red', 'Green', 'Blue']} /> <!-- Object options --> <MultiSelect options={[ { label: 'Red', value: '#ff0000', hex: true }, { label: 'Green', value: '#00ff00', hex: true }, ]} /> ``` 1. ```ts selected: Option[] = [] // bindable ``` **Your main state variable.** Array of currently selected options. Use `bind:selected` for two-way binding. ```svelte <script> let selected = $state(['Red']) // Preselect Red </script> <MultiSelect bind:selected options={colors} /> ``` 1. ```ts value: Option | Option[] | null = null // bindable ``` **Alternative to `selected`.** When `maxSelect={1}`, `value` is the single selected item (not an array). Otherwise, `value` equals `selected`. ```svelte <!-- Single-select: value = 'Red' (not ['Red']) --> <MultiSelect bind:value options={colors} maxSelect={1} /> <!-- Multi-select: value = ['Red', 'Blue'] (same as selected) --> <MultiSelect bind:value options={colors} /> ``` 1. ```ts maxSelect: number | null = null ``` **Controls selection behavior.** `null` = unlimited, `1` = single select, `2+` = limited multi-select. ```svelte <!-- Unlimited selection --> <MultiSelect options={colors} /> <!-- Single selection --> <MultiSelect options={colors} maxSelect={1} /> <!-- Max 3 selections --> <MultiSelect options={colors} maxSelect={3} /> ``` 1. ```ts placeholder: string | { text: string; persistent?: boolean } | null = null ``` Text shown when no options are selected. Can be a simple string or an object with extended options: ```svelte <!-- Simple string --> <MultiSelect placeholder="Choose..." /> <!-- Object with persistent option (stays visible even when options selected) --> <MultiSelect placeholder={{ text: 'Add items...', persistent: true }} /> ``` 1. ```ts disabled: boolean = false ``` Disables the component. Users can't interact with it, but it's still rendered. 1. ```ts required: boolean | number = false ``` For form validation. `true` means at least 1 option required, numbers specify exact minimum. ### Commonly Used Props 1. ```ts searchText: string = `` // bindable ``` The text user entered to filter options. Bindable for external control. 1. ```ts open: boolean = false // bindable ``` Whether the dropdown is visible. Bindable for external control. 1. ```ts allowUserOptions: boolean | `append` = false ``` Whether users can create new options by typing. `true` = add to selected only, `'append'` = add to both options and selected. 1. ```ts allowEmpty: boolean = false ``` Whether to allow the component to exist with no options. If `false`, shows console error when no options provided (unless `loading`, `disabled`, or `allowUserOptions` is `true`). 1. ```ts loading: boolean = false ``` Shows a loading spinner. Useful when fetching options asynchronously. 1. ```ts invalid: boolean = false // bindable ``` Marks the component as invalid (adds CSS class). Automatically set during form validation. ### Advanced Props 1. ```ts loadOptions: LoadOptionsFn | LoadOptionsConfig = undefined ``` **Dynamic loading for large datasets.** Enables lazy loading / infinite scroll instead of passing static `options`. Pass either a function or an object with config: ```svelte <!-- Simple: just a function --> <MultiSelect loadOptions={myFetchFn} /> <!-- With config --> <MultiSelect loadOptions={{ fetch: myFetchFn, debounceMs: 500, batchSize: 20 }} /> ``` The function receives `{ search, offset, limit }` and must return `{ options, hasMore }`: ```ts async function load_options({ search, offset, limit }) { const response = await fetch(`/api/items?q=${search}&skip=${offset}&take=${limit}`) const { items, total } = await response.json() return { options: items, hasMore: offset + limit < total } } ``` Config options (when passing an object): | Key | Type | Default | Description | | ------------ | --------- | ------- | ------------------------------------------- | | `fetch` | `fn` | β€” | Async function to load options (required) | | `debounceMs` | `number` | `300` | Debounce delay for search queries | | `batchSize` | `number` | `50` | Number of options to load per batch | | `onOpen` | `boolean` | `true` | Whether to load options when dropdown opens | Features automatic state management, debounced search, infinite scroll pagination, and loading indicators. See the [infinite-scroll demo](https://janosh.github.io/svelte-multiselect/infinite-scroll) for live examples. 1. ```ts activeIndex: number | null = null // bindable ``` Zero-based index of currently active option in the filtered list. 1. ```ts activeOption: Option | null = null // bindable ``` Currently active option (hovered or navigated to with arrow keys). 1. ```ts createOptionMsg: string | ((state: { searchText: string; selected: Option[]; options: Option[]; matchingOptions: Option[] }) => string) | null = `Create this option...` ``` Message shown when `allowUserOptions` is enabled and user can create a new option. Can be a static string or a function that receives component state and returns a dynamic message. 1. ```ts duplicates: boolean | 'case-insensitive' = false ``` Controls duplicate detection. `false` (default) blocks exact duplicates. `true` allows selecting the same option multiple times. `'case-insensitive'` blocks case variants (e.g. "Apple" blocks "apple"). <!-- deno-fmt-ignore --> 1. ```ts filterFunc: (opt: Option, searchText: string) => boolean ``` Custom function to filter options based on search text. Default filters by label. <!-- deno-fmt-ignore --> 1. ```ts key: (opt: Option) => unknown ``` Function to determine option equality. Default compares by lowercased label. 1. ```ts closeDropdownOnSelect: boolean | 'if-mobile' | 'retain-focus' = false ``` Whether to close dropdown after selection. `false` (default) keeps dropdown open for rapid multi-selection. `true` closes after each selection. `'if-mobile'` closes on mobile devices only (screen width below `breakpoint`). `'retain-focus'` closes dropdown but keeps input focused for rapid typing to create custom options from text input (see `allowUserOptions`). 1. ```ts resetFilterOnAdd: boolean = true ``` Whether to clear search text when an option is selected. 1. ```ts sortSelected: boolean | ((a: Option, b: Option) => number) = false ``` Whether/how to sort selected options. `true` uses default sort, function enables custom sorting. 1. ```ts portal: { target_node?: HTMLElement; active?: boolean } = {} ``` Configuration for portal rendering. When `active: true`, the dropdown is rendered at document.body level with fixed positioning. Useful for avoiding z-index and overflow issues. ### Grouping Props Group related options together with visual headers. Add a `group` key to your option objects: ```svelte <script> const options = [ { label: `JavaScript`, group: `Frontend` }, { label: `TypeScript`, group: `Frontend` }, { label: `Python`, group: `Backend` }, { label: `Go`, group: `Backend` }, ] </script> <MultiSelect {options} collapsibleGroups groupSelectAll /> ``` See the [grouping demo](https://janosh.github.io/svelte-multiselect/grouping) for live examples. 1. ```ts collapsibleGroups: boolean = false ``` Enable click-to-collapse groups. When `true`, users can click group headers to hide/show options in that group. 1. ```ts collapsedGroups: Set<string> = new Set() ``` Bindable set of collapsed group names. Use `bind:collapsedGroups` to control which groups are collapsed externally or to persist collapse state. 1. ```ts groupSelectAll: boolean = false ``` Add a "Select all" button to each group header, allowing users to select all options in a specific group at once. 1. ```ts ungroupedPosition: 'first' | 'last' = 'first' ``` Where to render options that don't have a `group` key. `'first'` places them at the top, `'last'` at the bottom. 1. ```ts groupSortOrder: 'none' | 'asc' | 'desc' | ((a: string, b: string) => number) = 'none' ``` Sort groups alphabetically (`'asc'` or `'desc'`) or with a custom comparator function. Default `'none'` preserves order of first occurrence. 1. ```ts searchExpandsCollapsedGroups: boolean = false ``` When `true`, collapsed groups automatically expand when the search query matches options within them. 1. ```ts searchMatchesGroups: boolean = false ``` When `true`, the search query also matches against group names, not just option labels. If a group name matches, all options in that group are shown. 1. ```ts keyboardExpandsCollapsedGroups: boolean = false ``` When `true`, collapsed groups automatically expand when the user navigates into them with arrow keys. 1. ```ts stickyGroupHeaders: boolean = false ``` When `true`, group headers stick to the top of the dropdown while scrolling through their options. 1. ```ts collapseAllGroups: () => void // bindable ``` Programmatically collapse all groups. Use with `bind:collapseAllGroups` to get a callable function. 1. ```ts expandAllGroups: () => void // bindable ``` Programmatically expand all groups. Use with `bind:expandAllGroups` to get a callable function. 1. ```ts liGroupHeaderClass: string = '' ``` CSS class applied to group header `<li>` elements. 1. ```ts liGroupHeaderStyle: string | null = null ``` Inline style for group header elements. 1. ```ts groupHeader: Snippet<[{ group: string; options: T[]; collapsed: boolean }]> ``` Custom snippet for rendering group headers. Receives the group name, array of options in that group, and whether the group is collapsed. 1. ```ts ongroupToggle: (data: { group: string; collapsed: boolean }) => void ``` Callback fired when a group is collapsed or expanded. Receives the group name and its new collapsed state. ### Form & Accessibility Props 1. ```ts id: string | null = null ``` Applied to the `<input>` for associating with `<label>` elements. 1. ```ts name: string | null = null ``` Form field name for form submission. When selected options are displayed as chips (the default display mode), they submit as `JSON.stringify(selected)`. Prefer stable object `value` fields for server processing, or customize serialization with `formSerialize`. 1. ```ts formSerialize: (selected: Option[]) => string | null = JSON.stringify ``` Customizes the submitted value in chip mode. For object options, use `formSerialize={(selected) => selected.map(({ value }) => value).join(',')}`. For primitive options, use `formSerialize={(selected) => selected.join(',')}`. 1. ```ts autocomplete: string = 'off' ``` Browser autocomplete behavior. Usually `'on'` or `'off'`. 1. ```ts inputmode: string | null = null ``` Hint for mobile keyboard type (`'numeric'`, `'tel'`, `'email'`, etc.). Set to `'none'` to hide keyboard. 1. ```ts pattern: string | null = null ``` Regex pattern for input validation. ### UI & Behavior Props 1. ```ts maxOptions: number | undefined = undefined ``` Limit number of options shown in dropdown. `undefined` = no limit. 1. ```ts minSelect: number | null = null ``` Minimum selections required before remove buttons appear. 1. ```ts autoScroll: boolean = true ``` Whether to keep active option in view when navigating with arrow keys. 1. ```ts breakpoint: number = 800 ``` Screen width (px) that separates 'mobile' from 'desktop' behavior. 1. ```ts fuzzy: boolean = true ``` Whether to use fuzzy matching for filtering options. When `true` (default), matches non-consecutive characters (e.g., "ga" matches "Grapes" and "Green Apple"). When `false`, uses substring matching only. 1. ```ts highlightMatches: boolean = true ``` Whether to highlight matching text in dropdown options. 1. ```ts keepSelectedInDropdown: false | 'plain' | 'checkboxes' = false ``` Controls whether selected options remain visible in dropdown. `false` (default) hides selected options. `'plain'` shows them with visual distinction. `'checkboxes'` prefixes each option with a checkbox. 1. ```ts selectAllOption: boolean | string = false ``` Adds a "Select All" option at the top of the dropdown. `true` shows default label, or pass a custom string label. 1. ```ts liSelectAllClass: string = '' ``` CSS class applied to the "Select All" `<li>` element. 1. ```ts parseLabelsAsHtml: boolean = false ``` Whether to render option labels as HTML. **Warning:** Don't combine with `allowUserOptions` (XSS risk). 1. ```ts selectedOptionsDraggable: boolean = !sortSelected ``` Whether selected options can be reordered by dragging. 1. ```ts selectedFlipParams: FlipParams = { duration: 100 } ``` Animation parameters for the [Svelte flip animation](https://svelte.dev/docs/svelte/svelte-animate) when reordering selected options via drag-and-drop. Set `{ duration: 0 }` to disable animation. Accepts `duration`, `delay`, and `easing` properties. ### Keyboard Shortcuts 1. ```ts shortcuts: Partial<KeyboardShortcuts> = {} ``` Override default keyboard shortcuts. Shortcut format: `"modifier+...+key"` where modifiers can be `ctrl`, `shift`, `alt`, `meta`, `cmd`. Set a shortcut to `null` to disable it. Custom shortcuts take precedence over built-in key handlers (Enter, Escape, ArrowUp/Down, Backspace). Available shortcuts and their defaults: | Key | Default | Action | | ------------ | ----------------------------------- | ------------------------------------------- | | `select_all` | `'ctrl+a'` | Select all visible options | | `clear_all` | `'ctrl+shift+a'` | Deselect all options | | `open` | `null` | Open dropdown | | `close` | `null` | Close dropdown (Escape works by default) | | `undo` | `'meta+z'` / `'ctrl+z'` | Undo last selection change (platform-aware) | | `redo` | `'meta+shift+z'` / `'ctrl+shift+z'` | Redo last undone change (platform-aware) | ### Selection History (Undo/Redo) 1. ```ts history: boolean | number = true ``` Enable selection history for undo/redo support. `true` (default) stores up to 50 states. Pass a number to set a custom maximum. `false` or `0` disables history. Note: you need at least `history=2` for a single undo (history=1 effectively disables it). 1. ```ts undo: () => boolean // bindable ``` Undo the last selection change. Returns `true` if undo was performed. Use with `bind:undo` to get a callable function. 1. ```ts redo: () => boolean // bindable ``` Redo the last undone selection change. Returns `true` if redo was performed. Use with `bind:redo` to get a callable function. 1. ```ts canUndo: boolean // bindable ``` Whether an undo operation is available. Use with `bind:canUndo` for UI indicators (e.g. disabling an undo button). 1. ```ts canRedo: boolean // bindable ``` Whether a redo operation is available. Use with `bind:canRedo` for UI indicators (e.g. disabling a redo button). ### Message Props 1. ```ts noMatchingOptionsMsg: string = 'No matching options' ``` Message when search yields no results. 1. ```ts duplicateOptionMsg: string = 'This option is already selected' ``` Message when user tries to create duplicate option. 1. ```ts defaultDisabledTitle: string = 'This option is disabled' ``` Tooltip for disabled options. 1. ```ts disabledInputTitle: string = 'This input is disabled' ``` Tooltip when component is disabled. 1. ```ts removeAllTitle: string = 'Remove all' ``` Tooltip for remove-all button. 1. ```ts removeBtnTitle: string = 'Remove' ``` Tooltip for individual remove buttons. <!-- deno-fmt-ignore --> 1. ```ts maxSelectMsg: ((current: number, max: number) => string) | null ``` Function to generate "X of Y selected" message. `null` = no message. ### DOM Element References (bindable) These give you access to DOM elements after the component mounts: 1. ```ts input: HTMLInputElement | null = null // bindable ``` Handle to the main `<input>` DOM element. 1. ```ts form_input: HTMLInputElement | null = null // bindable ``` Handle to the hidden form input used for validation. 1. ```ts outerDiv: HTMLDivElement | null = null // bindable ``` Handle to the outer wrapper `<div>` element. ### Styling Props For custom styling with CSS frameworks or one-off styles: 1. ```ts style: string | null = null ``` CSS rules for the outer wrapper div. 1. ```ts inputStyle: string | null = null ``` CSS rules for the main input element. 1. ```ts ulSelectedStyle: string | null = null ``` CSS rules for the selected options list. 1. ```ts ulOptionsStyle: string | null = null ``` CSS rules for the dropdown options list. 1. ```ts liSelectedStyle: string | null = null ``` CSS rules for selected option list items. 1. ```ts liOptionStyle: string | null = null ``` CSS rules for dropdown option list items. ### CSS Class Props For use with CSS frameworks like Tailwind: 1. ```ts outerDivClass: string = '' ``` CSS class for outer wrapper div. 1. ```ts inputClass: string = '' ``` CSS class for main input element. 1. ```ts ulSelectedClass: string = '' ``` CSS class for selected options list. 1. ```ts ulOptionsClass: string = '' ``` CSS class for dropdown options list. 1. ```ts liSelectedClass: string = '' ``` CSS class for selected option items. 1. ```ts liOptionClass: string = '' ``` CSS class for dropdown option items. 1. ```ts liActiveOptionClass: string = '' ``` CSS class for the currently active dropdown option. 1. ```ts liUserMsgClass: string = '' ``` CSS class for user messages (no matches, create option, etc.). 1. ```ts liActiveUserMsgClass: string = '' ``` CSS class for active user messages. 1. ```ts maxSelectMsgClass: string = '' ``` CSS class for the "X of Y selected" message. ### Read-only Props (bindable) These reflect internal component state: 1. ```ts matchingOptions: Option[] = [] // bindable ``` Currently filtered options based on search text. ### Bindable Props `selected`, `value`, `searchText`, `open`, `activeIndex`, `activeOption`, `invalid`, `input`, `outerDiv`, `form_input`, `options`, `matchingOptions`, `collapsedGroups`, `collapseAllGroups`, `expandAllGroups`, `undo`, `redo`, `canUndo`, `canRedo` ## 🎰 &thinsp; Snippets `MultiSelect.svelte` accepts the following named snippets: 1. `#snippet option({ option, idx, selected, active, disabled })`: Customize rendering of dropdown options. Receives the `option`, its zero-indexed position (`idx`) in the dropdown, whether it is `selected`, `active` (keyboard-highlighted), and `disabled`. 1. `#snippet selectedItem({ option, idx })`: Customize rendering of selected items. Receives as props an `option` and the zero-indexed position (`idx`) it has in the list of selected items. 1. `#snippet children({ option, idx, type })`: Convenience snippet that applies to both dropdown options AND selected items. Use this when you want the same custom rendering for both. Takes precedence if `option` or `selectedItem` are not provided. `type` is `'selected'` when rendering a selected pill and `'option'` when rendering a dropdown item, allowing conditional styling/content by context. 1. `#snippet spinner()`: Custom spinner component to display when in `loading` state. Receives no props. 1. `#snippet disabledIcon()`: Custom icon to display inside the input when in `disabled` state. Receives no props. Use an empty `{#snippet disabledIcon()}{/snippet}` to remove the default disabled icon. 1. `#snippet expandIcon({ open, disabled })`: Allows setting a custom icon to indicate to users that the Multiselect text input field is expandable into a dropdown list. `open` is `true` if the dropdown is visible and `false` if hidden. `disabled` reflects the component's disabled state. 1. `#snippet removeIcon({ option, isRemoveAll })`: Custom icon to display as remove button. Used both by per-option remove buttons (`isRemoveAll: false`, `option` is the item being removed) and the 'remove all' button (`isRemoveAll: true`, `option` is `undefined`). 1. `#snippet userMsg({ searchText, msgType, msg })`: Displayed like a dropdown item when the list is empty and user is allowed to create custom options based on text input (or if the user's text input clashes with an existing option). Receives props: - `searchText`: The text user typed into search input. - `msgType: false | 'create' | 'dupe' | 'no-match'`: `'dupe'` means user input is a duplicate of an existing option. `'create'` means user is allowed to convert their input into a new option not previously in the dropdown. `'no-match'` means user input doesn't match any dropdown items and users are not allowed to create new options. `false` means none of the above. - `msg`: Will be `duplicateOptionMsg` or `createOptionMsg` (see [props](#πŸ”£-props)) based on whether user input is a duplicate or can be created as new option. Note this snippet replaces the default UI for displaying these messages so the snippet needs to render them instead (unless purposely not showing a message). 1. `#snippet afterInput({ selected, disabled, invalid, id, placeholder, open, required, searchText })`: Placed after the search input. For arbitrary content like icons or temporary messages. Can serve as a more dynamic, more customizable alternative to the `placeholder` prop. Example using several snippets: ```svelte <MultiSelect options={[`Red`, `Green`, `Blue`, `Yellow`, `Purple`]}> {#snippet children({ idx, option, type })} <span style="display: flex; align-items: center; gap: 6pt"> <span style:background={`${option}`} style="border-radius: 50%; width: 1em; height: 1em" ></span> {#if type === `option`}{idx + 1}{/if} {option} </span> {/snippet} {#snippet spinner()} <CustomSpinner /> {/snippet} {#snippet removeIcon({ isRemoveAll })} <strong>{isRemoveAll ? `Clear` : `X`}</strong> {/snippet} </MultiSelect> ``` ## 🎬 &thinsp; Events `MultiSelect.svelte` provides the following event callback props: 1. ```ts onadd={({ option, selected }) => console.log(option, selected)} ``` Triggers when a new option is selected. `option` is the newly selected option, `selected` is the updated array of all selected options. 1. ```ts oncreate={({ option }) => console.log(option)} ``` Triggers when a user creates a new option (when `allowUserOptions` is enabled). The created option is provided as `option`. 1. ```ts onremove={({ option, selected }) => console.log(option, selected)} ``` Triggers when a single selected option is removed. `option` is the removed option, `selected` is the updated array of remaining selected options. 1. ```ts onremoveAll={({ options }) => console.log(options)} ``` Triggers when all selected options are removed. The `options` payload gives the options that were removed (might not be all if `minSelect` is set). 1. ```ts onselectAll={({ options }) => console.log(options)} ``` Triggers when the "Select All" option is clicked (requires `selectAllOption` to be enabled). The `options` payload contains the options that were added. 1. ```ts onreorder={({ options, previous }) => console.log(options, previous)} ``` Triggers when selected options are reordered via drag-and-drop (enabled by default when `sortSelected` is false). `options` is the newly ordered array, `previous` is the array before reordering. 1. ```ts onchange={({ type, option, options }) => console.log(type, option ?? options)} ``` Triggers when an option is either added (selected) or removed from selected, all selected options are removed at once, or selected options are reordered via drag-and-drop. `type` is one of `'add' | 'remove' | 'removeAll' | 'selectAll' | 'reorder'` and payload will be `option: Option` or `options: Option[]`, respectively. 1. ```ts onopen={({ event }) => console.log(`Dropdown opened by`, event)} ``` Triggers when the dropdown list of options appears. `event` is the DOM's `FocusEvent`, `KeyboardEvent` or `ClickEvent` that triggered the open. 1. ```ts onclose={({ event }) => console.log(`Dropdown closed by`, event)} ``` Triggers when the dropdown list of options disappears. `event` is the DOM's `FocusEvent`, `KeyboardEvent` or `ClickEvent` that triggered the close. 1. ```ts onsearch={({ searchText, matchingOptions }) => console.log(searchText, matchingOptions.length)} ``` Triggers (debounced, 150ms) when the search text changes. Useful for analytics or loading remote options. `searchText` is the current input value, `matchingOptions` is the array of options matching the search. 1. ```ts onmaxreached={({ selected, maxSelect, attemptedOption }) => console.log(attemptedOption)} ``` Triggers when a user tries to select more options than `maxSelect` allows. Useful for showing feedback. Does not fire for `maxSelect=1` (which uses replace behavior). 1. ```ts onduplicate={({ option }) => console.log(`Duplicate:`, option)} ``` Triggers when a user tries to add an already-selected option (when `duplicates=false`). Useful for showing feedback to the user. 1. ```ts onactivate={({ option, index }) => console.log(`Active:`, option, index)} ``` Triggers during keyboard navigation (ArrowUp/ArrowDown) through options. `option` is the newly active option, `index` is its position. Does not fire on mouse hover. 1. ```ts oncollapseAll={({ groups }) => console.log(`Collapsed:`, groups)} ``` Triggers when all groups are collapsed (e.g. via `collapseAllGroups()`). `groups` lists the group names that were collapsed. 1. ```ts onexpandAll={({ groups }) => console.log(`Expanded:`, groups)} ``` Triggers when all groups are expanded (e.g. via `expandAllGroups()`). `groups` lists the group names that were expanded. 1. ```ts onundo={({ previous, current }) => console.log(`Undo:`, previous, `β†’`, current)} ``` Triggers when an undo operation restores a previous selection state. `previous` is the selection before undo, `current` is the restored selection. 1. ```ts onredo={({ previous, current }) => console.log(`Redo:`, previous, `β†’`, current)} ``` Triggers when a redo operation re-applies a previously undone selection change. `previous` is the selection before redo, `current` is the new selection. For example, here's how you might annoy your users with an alert every time one or more options are added or removed: ```svelte <MultiSelect onchange={({ type, option, options }) => { if (type === 'add') alert(`You added ${option}`) if (type === 'remove') alert(`You removed ${option}`) if (type === 'removeAll') alert(`You removed ${options}`) if (type === 'selectAll') alert(`You selected all: ${options}`) if (type === 'reorder') alert(`New order: ${options}`) }} /> ``` > Note: Depending on the data passed to the component the `option(s)` payload will either be objects or simple strings/numbers. This component also forwards many DOM events from the `<input>` node: `blur`, `change`, `click`, `keydown`, `keyup`, `mousedown`, `mouseenter`, `mouseleave`, `touchcancel`, `touchend`, `touchmove`, `touchstart`. Registering listeners for these events works the same: ```svelte <MultiSelect options={[1, 2, 3]} onkeyup={(event) => console.log('key', event.target.value)} /> ``` ## 🦺 &thinsp; TypeScript The type of `options` is inferred automatically from the data you pass. E.g. ```ts const options = [ { label: `foo`, value: 42 } { label: `bar`, value: 69 } ] // type Option = { label: string, value: number } const options = [`foo`, `bar`] // type Option = string const options = [42, 69] // type Option = number ``` The inferred type of `Option` is used to enforce type-safety on derived props like `selected` as well as snippets. E.g. you'll get an error when trying to use a snippet that expects a string if your options are objects (see [this comment](https://github.com/janosh/svelte-multiselect/pull/189/files#r1058853697) for example screenshots). You can also import [the types this component uses](https://github.com/janosh/svelte-multiselect/blob/main/src/lib/index.ts) for downstream applications: ```ts import { LoadOptions, // Dynamic option loading callback LoadOptionsConfig, LoadOptionsFn, LoadOptionsParams, LoadOptionsResult, FormSerialize, // Type signature for custom form serialization MultiSelectEvents, MultiSelectSnippets, ObjectOption, Option, } from 'svelte-multiselect' ``` ### Subpath Exports This package also provides subpath exports for utilities used by the component: ```ts import { click_outside, draggable, highlight_matches, sortable, tooltip, } from 'svelte-multiselect/attachments' import { fuzzy_match, get_label } from 'svelte-multiselect/utils' import { heading_anchors } from 'svelte-multiselect/heading-anchors' ``` ## ✨ &thinsp; Styling There are 3 ways to style this component. To understand which options do what, it helps to keep in mind this simplified DOM structure of the component: ```svelte <div class="multiselect"> <ul class="selected"> <li>Selected 1</li> <li>Selected 2</li> </ul> <ul class="options"> <li>Option 1</li> <li>Option 2</li> </ul> </div> ``` ### With CSS variables If you only want to make small adjustments, you can pass the following CSS variables directly to the component as props or define them in a `:global()` CSS context. All variables have sensible defaults defined inside `MultiSelect.svelte` itself. Minimal example that changes the background color of the options dropdown: ```svelte <MultiSelect --sms-options-bg="white" /> ``` - `div.multiselect` - `border: var(--sms-border, 1pt solid light-dark(lightgray, #555))`: Change this to e.g. to `1px solid red` to indicate this form field is in an invalid state. - `border-radius: var(--sms-border-radius, 3pt)` - `padding: var(--sms-padding, 0 3pt)` - `background: var(--sms-bg, light-dark(white, #222226))` - `color: var(--sms-text-color)` - `min-height: var(--sms-min-height, 22pt)` - `width: var(--sms-width)` - `max-width: var(--sms-max-width)` - `margin: var(--sms-margin)` - `font-size: var(--sms-font-size, inherit)` - `div.multiselect.open` - `z-index: var(--sms-open-z-index, 4)`: Increase this if needed to ensure the dropdown list is displayed atop all other page elements. - `div.multiselect:focus-within` - `border: var(--sms-focus-border, 1pt solid var(--sms-active-color, cornflowerblue))`: Border when component has focus. Defaults to `--sms-active-color` which in turn defaults to `cornflowerblue`. - `div.multiselect.disabled` - `background: var(--sms-disabled-bg, light-dark(lightgray, #444))`: Background when in disabled state. - `div.multiselect input::placeholder` - `color: var(--sms-placeholder-color)` - `opacity: var(--sms-placeholder-opacity)` - `div.multiselect > ul.selected > li` - `background: var(--sms-selected-bg, light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.15)))`: Background of selected options. - `padding: var(--sms-selected-li-padding, 0 2pt 0 5pt)`: Padding of selected options. - `color: var(--sms-selected-text-color, var(--sms-text-color))`: Text color for selected options. - `ul.selected > li button:hover, button.remove-all:hover, button:focus` - `color: var(--sms-remove-btn-hover-color, inherit)`: Color of the remove-icon buttons for removing all or individual selected options when in `:focus` or `:hover` state. - `background: var(--sms-remove-btn-hover-bg, light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2)))`: Background for hovered remove buttons. - `div.multiselect > ul.options` - `background: var(--sms-options-bg, light-dark(#fafafa, #222226))`: Background of dropdown list. - `max-height: var(--sms-options-max-height, 50vh)`: Maximum height of options dropdown. - `overscroll-behavior: var(--sms-options-overscroll, none)`: Whether scroll events bubble to parent elements when reaching the top/bottom of the options dropdown. See [MDN](https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior). - `z-index: var(--sms-options-z-index, 3)`: Z-index for the dropdown options list. - `box-shadow: var(--sms-options-shadow, light-dark(0 0 14pt -8pt black, 0 0 14pt -4pt rgba(0, 0, 0, 0.8)))`: Box shadow of dropdown list. - `border: var(--sms-options-border)` - `border-width: var(--sms-options-border-width, 1px)` - `border-radius: var(--sms-options-border-radius, 1ex)` - `padding: var(--sms-options-padding, 0)` - `margin: var(--sms-options-margin, 6pt 0 0 0)` - `div.multiselect > ul.options > li` - `scroll-margin: var(--sms-options-scroll-margin, 100px)`: Top/bottom margin to keep between dropdown list items and top/bottom screen edge when auto-scrolling list to keep items in view. - `div.multiselect > ul.options > li.selected` - `background: var(--sms-li-selected-plain-bg, light-dark(rgba(0, 123, 255, 0.1), rgba(100, 180, 255, 0.2)))`: Background of selected list items in options pane. - `border-left: var(--sms-li-selected-plain-border, 1px solid var(--sms-active-color, cornflowerblue))`: Left border of selected list items in options pane. - `div.multiselect > ul.options > li.active` - `background: var(--sms-li-active-bg, var(--sms-active-color, light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.15))))`: Background of active options. Options in the dropdown list become active either by mouseover or by navigating to them with arrow keys. Selected options become active when `selectedOptionsDraggable=true` and an option is being dragged to a new position. Note the active option in that case is not the dragged option but the option under it whose place it will take on drag end. - `div.multiselect > ul.options > li.disabled` - `background: var(--sms-li-disabled-bg, light-dark(#f5f5f6, #2a2a2a))`: Background of disabled options in the dropdown list. - `color: var(--sms-li-disabled-text, light-dark(#b8b8b8, #666))`: Text color of disabled option in the dropdown list. - `div.multiselect > ul.options > li.select-all` - `border-bottom: var(--sms-select-all-border-bottom, 1px solid light-dark(lightgray, #555))`: Bottom border separating "Select All" from regular options. - `font-weight: var(--sms-select-all-font-weight, 500)`: Font weight of "Select All" text. - `color: var(--sms-select-all-color, inherit)`: Text color of "Select All" option. - `background: var(--sms-select-all-bg, transparent)`: Background of "Select All" option. - `margin-bottom: var(--sms-select-all-margin-bottom, 2pt)`: Space below "Select All" option. - `background (hover): var(--sms-select-all-hover-bg, ...)`: Background of "Select All" on hover. Falls back to `--sms-li-active-bg` then `--sms-active-color`. - `div.multiselect > ul.options > li.group-header` - `font-weight: var(--sms-group-header-font-weight, 600)`: Font weight of group headers. - `font-size: var(--sms-group-header-font-size, 0.9em)`: Font size of group headers. - `color: var(--sms-group-header-color, light-dark(#666, #aaa))`: Text color of group headers. - `background: var(--sms-group-header-bg, transparent)`: Background of group headers. - `padding: var(--sms-group-header-padding, 2pt 1ex)`: Padding around group header text. - `text-transform: var(--sms-group-header-text-transform, uppercase)`: Text transform for group headers. - `letter-spacing: var(--sms-group-header-letter-spacing, 0.5px)`: Letter spacing for group headers. - `margin-top: var(--sms-group-header-margin-top, 4pt)`: Top margin for group headers (except the first). - `border-top: var(--sms-group-header-border-top, 1px solid light-dark(#eee, #333))`: Top border for group headers (except the first). - `background (hover): var(--sms-group-header-hover-bg, light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.05)))`: Background of collapsible group headers on hover. - `background (sticky): var(--sms-group-header-sticky-bg, ...)`: Background when `stickyGroupHeaders` is enabled. Falls back to `--sms-options-bg`. - `div.multiselect > ul.options > li` (grouped options) - `padding-left: var(--sms-group-item-padding-left, var(--sms-group-option-indent, 1.5ex))`: Indentation for options within a group. - Group chevron icon - `transition: transform var(--sms-group-collapse-duration, 0.15s) ease-out`: Animation duration for group collapse/expand chevron rotation. - Group "Select/Deselect All" button - `background (hover): var(--sms-group-select-all-hover-bg, light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1)))`: Background of per-group select-all button on hover. - `color (deselect): var(--sms-group-deselect-color, light-dark(#c44, #f77))`: Text color of "Deselect All" button (when all group options are already selected). - `::highlight(sms-search-matches)`: applies to search results in dropdown list that match the current search query if `highlightMatches=true`. These styles [cannot be set via CSS variables](https://stackoverflow.com/a/56799215). Instead, use a new rule set. For example: ```css ::highlight(sms-search-matches) { color: orange; background: rgba(0, 0, 0, 0.15); text-decoration: underline; } ``` ### With CSS frameworks The second method allows you to pass in custom classes to the important DOM elements of this component to target them with frameworks like [Tailwind CSS](https://tailwindcss.com). - `outerDivClass`: wrapper `div` enclosing the whole component - `ulSelectedClass`: list of selected options - `liSelectedClass`: selected list items - `ulOptionsClass`: available options listed in the dropdown when component is in `open` state - `liOptionClass`: list items selectable from dropdown list - `liActiveOptionClass`: the currently active dropdown list item (i.e. hovered or navigated to with arrow keys) - `liSelectAllClass`: the "Select All" option at the top of the dropdown (when `selectAllOption` is enabled) - `liUserMsgClass`: user message (last child of dropdown list when no options match user input) - `liActiveUserMsgClass`: user message when active (i.e. hovered or navigated to with arrow keys) - `maxSelectMsgClass`: small span towards the right end of the input field displaying to the user how many of the allowed number of options they've already selected This simplified version of the DOM structure of the component shows where these classes are inserted: ```svelte <div class="multiselect {outerDivClass}"> <input class={inputClass} /> <ul class="selected {ulSelectedClass}"> <li class={liSelectedClass}>Selected 1</li> <li class={liSelectedClass}>Selected 2</li> </ul> <span class="maxSelectMsgClass">2/5 selected</span> <ul class="options {ulOptionsClass}"> <li class="select-all {liSelectAllClass}">Select all</li> <li class={liOptionClass}>Option 1</li> <li class="{liOptionClass} {liActiveOptionClass}"> Option 2 (currently active) </li> ... <li class="{liUserMsgClass} {liActiveUserMsgClass}"> Create this option... </li> </ul> </div> ``` ### With global CSS Odd as it may seem, you get the most fine-grained control over the styling of every part of this component by using the following `:global()` CSS selectors. `ul.selected` is the list of currently selected options rendered inside the component's input whereas `ul.options` is the list of available options that slides out when the component is in its `open` state. See also [simplified DOM structure](#styling). ```css :global(div.multiselect) { /* top-level wrapper div */ } :global(div.multiselect.open) { /* top-level wrapper div when dropdown open */ } :global(div.multiselect.disabled) { /* top-level wrapper div when in disabled state */ } :global(div.multiselect > ul.selected) { /* selected list */ } :global(div.multiselect > ul.selected > li) { /* selected list items */ } :global(div.multiselect button) { /* target all buttons in this component */ } :global(div.multiselect > ul.selected > li button, button.remove-all) { /* buttons to remove a single or all selected options at once */ } :global(div.multiselect > input[autocomplete]) { /* input inside the top-level wrapper div */ } :global(div.multiselect > ul.options) { /* dropdown options */ } :global(div.multiselect > ul.options > li) { /* dropdown list items */ } :global(div.multiselect > ul.options > li.selected) { /* selected options in the dropdown list */ } :global(div.multiselect > ul.options > li:not(.selected):hover) { /* unselected but hovered options in the dropdown list */ } :global(div.multiselect > ul.options > li.active) { /* active means item was navigated to with up/down arrow keys */ /* ready to be selected by pressing enter */ } :global(div.multiselect > ul.options > li.disabled) { /* options with disabled key set to true (see props above) */ } :global(div.multiselect > ul.options > li.select-all) { /* the "Select All" option at the top of the dropdown */ } ``` ## πŸ†• &thinsp; Changelog [View the changelog](changelog.md). ## πŸ™ &thinsp; Contributing Here are some steps to [get you started](contributing.md) if you'd like to contribute to this project!

JavaScript Libraries & Components Web Components & Widgets
375 Github Stars
matterviz
Open Source

matterviz

<h1 align="center"> <sub><img src="static/favicon.svg" alt="Logo" width="40px"></sub> MatterViz </h1> <h4 align="center"> [![Tests](https://github.com/janosh/matterviz/actions/workflows/test.yml/badge.svg)](https://github.com/janosh/matterviz/actions/workflows/test.yml) [![GH Pages](https://github.com/janosh/matterviz/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/janosh/matterviz/actions/workflows/gh-pages.yml) [![VSCode Extension](https://img.shields.io/badge/Install%20VSCode-Extension-blue?logo=typescript&logoColor=white)](https://marketplace.visualstudio.com/items?itemName=janosh.matterviz) [![Docs](https://img.shields.io/badge/Read-the%20docs-blue?logo=googledocs&logoColor=white)](https://matterviz.janosh.dev) [![Open in StackBlitz](https://img.shields.io/badge/Open%20in-StackBlitz-darkblue?logo=stackblitz&logoColor=white)](https://stackblitz.com/github/janosh/matterviz) [![Zenodo DOI](https://zenodo.org/badge/498793280.svg)](https://doi.org/10.5281/zenodo.17094509) </h4> `matterviz` is a toolkit for building interactive web UIs for materials science: 3D crystal structures, molecules, MD/relaxation trajectories, periodic tables, phase diagrams, convex hulls, spectral data (bands, DOS, XRD), heatmaps, and scatter plots. ## πŸ”Œ &thinsp; [MatterViz VSCode Extension] Visualize crystal structures, molecules, and molecular dynamics trajectories [directly in VSCode][MatterViz VSCode Extension]. Features include: - Native support for common file formats (CIF, POSCAR, XYZ, TRAJ, HDF5, etc.) - Context menu (right click > "Render with MatterViz") and keyboard shortcuts (<kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>v</kbd> on Windows, <kbd>cmd</kbd>+<kbd>shift</kbd>+<kbd>v</kbd> on Mac) for quick access - Custom viewer for MD trajectories/geometry optimizations - **Extensive customization options** via VSCode settings - see [Configuration Guide](extensions/vscode/readme.md#️-configuration--customization) for examples [matterviz vscode extension]: https://marketplace.visualstudio.com/items?itemName=janosh.matterviz ## πŸ—ΊοΈ &thinsp; Roadmap - **βœ… MatterViz Web**: [matterviz.janosh.dev](https://matterviz.janosh.dev) - **βœ… MatterViz VSCode/Cursor**: [marketplace.visualstudio.com/items?itemName=janosh.matterviz](https://marketplace.visualstudio.com/items?itemName=janosh.matterviz) - **βœ… pymatviz**: [Jupyter](https://jupyter.org)/[Marimo](https://marimo.io) widgets for Python notebooks. See [`pymatviz` readme](https://github.com/janosh/pymatviz/blob/main/readme.md#interactive-widgets). ![Landing page showing 3D structure viewers](https://github.com/janosh/matterviz/releases/download/v0.2.2/2026-01-23-landing-page.webp) ## βš›οΈ &thinsp; 3D Structure Viewer Interactively visualize crystal structures and molecules. Supports drag-and-drop file loading for CIF, POSCAR, XYZ/EXTXYZ, pymatgen JSON, OPTIMADE JSON, and compressed formats. ![3D Structure Viewer](https://github.com/janosh/matterviz/releases/download/v0.2.2/2026-01-23-structure-viewer.webp) ## πŸ“Š &thinsp; Periodic Table Heatmap Visualize elemental properties across the periodic table. The inset scatter plot shows how properties vary with atomic number - here demonstrating the periodicity of first ionization energy. ![Periodic table heatmap](https://github.com/janosh/matterviz/releases/download/v0.2.2/2026-01-23-heatmap.webp) ## πŸ”¬ &thinsp; Element Details Pages Rich element pages with physical properties, electron configurations, Bohr atom visualizations, and element photos. ![Element details page for gold](https://github.com/janosh/matterviz/releases/download/v0.2.2/2026-01-23-details-page.webp) ## πŸ”¨ &thinsp; Installation ```sh npm add -D matterviz ``` ## πŸ“™ &thinsp; Usage ### Periodic Table ```svelte <script> import { PeriodicTable } from 'matterviz' const heatmap_values = { H: 10, He: 4, Li: 8, Fe: 3, O: 24 } </script> <PeriodicTable {heatmap_values} /> ``` ### Structure ```svelte <script> import { Structure } from 'matterviz' const data_url = '/structures/TiO2.cif' // supports .cif, .poscar, .xyz/.extxyz, pymatgen JSON, OPTIMADE JSON, .gz </script> <Structure {data_url} style="width: 500px; aspect-ratio: 1" /> ``` ### Composition ```svelte <script> import { Composition } from 'matterviz' // modes can be 'pie' (default) | 'bubble' | 'bar' </script> <Composition composition="LiFePO4" mode="pie" /> ``` ### Trajectory ```svelte <script> import { Trajectory } from 'matterviz' // supports .xyz/.extxyz, .traj, .hdf5, .npz, .pkl, .dat, .gz, .zip, .bz2, .xz </script> <Trajectory data_url="/traj/ase-md.xyz" auto_play fps={10} style="max-height: 700px" /> ``` ## πŸ§ͺ &thinsp; Coverage | Statements | Branches | Lines | | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | ![Statements](https://img.shields.io/badge/statements-99.84%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-82.92%25-yellow.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-99.84%25-brightgreen.svg?style=flat) | ## πŸ™ &thinsp; Acknowledgements - Element properties in `src/lib/element/data.ts` were combined from [`Bowserinator/Periodic-Table-JSON`](https://github.com/Bowserinator/Periodic-Table-JSON/blob/master/PeriodicTableJSON.json) under Creative Commons license and [`robertwb/Periodic Table of Elements.csv`](https://gist.github.com/robertwb/22aa4dbfb6bcecd94f2176caa912b952) (unlicensed). - Thanks to [Images of Elements](https://images-of-elements.com) for providing photos of elemental crystals and glowing excited gases. - Thanks to [@kadinzhang](https://github.com/kadinzhang) and their [Periodicity project](https://ptable.netlify.app) [[code](https://github.com/kadinzhang/Periodicity)] for the idea to display animated Bohr model atoms and inset a scatter plot into the periodic table to visualize the periodic nature of elemental properties. - Big thanks to all sources of element images. See [`fetch-elem-images.ts`](https://github.com/janosh/matterviz/blob/-/src/scripts/fetch-elem-images.ts) and [`static/elements`](https://github.com/janosh/matterviz/tree/main/static/elements). - Thanks to [@ixxie](https://github.com/ixxie) ([shenhav.fyi](https://shenhav.fyi)) for great suggestions. This project would not have been possible as a one-person side project without many fine open-source projects. πŸ™ To name just a few: | 3D graphics | 2D graphics | Docs | Bundler | Testing | | :-----------------------------: | :--------------------------------------: | :------------------------------------------: | :---------------------------------: | :----------------------------------: | | [three.js](https://threejs.org) | [d3](https://d3js.org) | [mdsvex](https://mdsvex.com) | [vite](https://vitejs.dev) | [playwright](https://playwright.dev) | | [threlte](https://threlte.xyz) | [sharp](https://sharp.pixelplumbing.com) | [rehype](https://github.com/rehypejs/rehype) | [sveltekit](https://kit.svelte.dev) | [vitest](https://vitest.dev) | ## How to cite `matterviz` Use [`citation.cff`](citation.cff) or cite the [Zenodo record](https://zenodo.org/badge/latestdoi/498793280) using the following BibTeX entry: ```bib @software{riebesell_matterviz_2022, title = {matterviz: visualization toolkit for materials informatics}, author = {Riebesell, Janosh and Evans, Matthew}, date = {2026-01-23}, year = {2026}, doi = {10.5281/zenodo.17094509}, url = {https://github.com/janosh/matterviz}, note = {10.5281/zenodo.17094509 - https://github.com/janosh/matterviz}, urldate = {2026-01-23}, % optional, replace with your date of access version = {0.3.1}, % replace with the version you use } ```

JavaScript Libraries & Components Data Visualisation
342 Github Stars