# Contributing ## Basic dev workflow Install pnpm i Run a local dev server on `localhost:3000`: pnpm dev ## Testing Lint: pnpm lint Fix most lint issues: pnpm lint:fix Run the tests: pnpm test Check code coverage: pnpm cover ## Other Benchmark runtime performance: pnpm benchmark:runtime Benchmark memory usage: pnpm benchmark:memory Benchmark bundle size: pnpm benchmark:bundlesize Benchmark storage size: pnpm benchmark:storage Run memory leak test: pnpm test:leak Build the GitHub Pages docs site: pnpm docs ## FAQs Some explanations of why the code is structured the way it is, in case it's confusing. ### Why a custom framework? It was [a good learning exercise](https://nolanlawson.com/2023/12/02/lets-learn-how-modern-javascript-frameworks-work-by-building-one/), and it reduced the bundle size quite a bit to switch from Svelte to a custom framework. Plus, `emoji-picker-element` no longer needs to keep up with breaking changes in Svelte or the tools in the Svelte ecosystem (e.g. Rollup and Jest plugins). ### What are some of the quirks of the custom framework? The framework mostly gets the job done, but I took a few shortcuts since we didn't need all the possible bells and whistles. Here is a brief description. First, all the DOM nodes and update functions for those nodes are kept in-memory via a `WeakMap` where the key is the `state`. There's one `state` per instance of the `Picker.js` Svelte-esque component. So when the instance is GC'ed, everything related to the DOM and update functions should be GC'ed. (The exception is the global `parseCache`, which only contains the clone-able `template` and bindings for each unique `tokens` array, which is unique per `html` tag template literal. These templates/bindings never changes per component instance, so it makes sense to just parse once and cache them forever, in case the `` element itself is constantly unmounted and re-created.) Second, I took a shortcut, which is that all unique (non-`