npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ryanatkn/fuz_code

v0.21.0

Published

syntax styling utilities and components for TypeScript, Svelte, SvelteKit

Downloads

272

Readme

@ryanatkn/fuz_code

syntax styling utilities and components for TypeScript, Svelte, SvelteKit 🎨

code.fuz.dev

fuz_code is a rework of Prism. The main changes:

  • has a minimal and explicit API to generate stylized HTML, and knows nothing about the DOM
  • uses stateless ES modules, instead of globals with side effects and pseudo-module behaviors
  • has various incompatible changes, so using Prism grammars requires some tweaks
  • smaller (by 7kB minified and 3kB gzipped, ~1/3 less) and faster
  • written in TypeScript

Like Prism, there are zero dependencies (unless you count Prism's @types/prismjs), but there are two optional dependencies, Svelte and the color-scheme-adaptive colors from Moss.

fuz_code provides optional builtin Svelte support with a Svelte grammar based on prism-svelte and a Svelte component for convenient usage.

The default theme integrates with my CSS library Moss. A zero-dependency fuz_code theme is also provided with some caveats, see below for more.

Compared to Shiki, this library is much lighter (with its faster shiki/engine/javascript, 503kB minified to 16kB, 63kb gzipped to 5.6kB), and vastly faster for runtime usage because it uses JS regexps instead of the Onigurama regexp engine used by TextMate grammars. Shiki also has 38 dependencies instead of 0. However this is not a fair comparison because Shiki is designed mainly for buildtime usage, and Prism grammars are much simpler and less powerful than TextMate's.

Usage

npm i -D @ryanatkn/fuz_code
import {syntax_styler} from '@ryanatkn/fuz_code';

syntax_styler.stylize('<h1>hello world</h1>', 'svelte');

Themes are just CSS files, so they work with any JS framework.

With SvelteKit:

// +layout.svelte
import '@ryanatkn/fuz_code/theme.css';

The primary themes (currently just one) have a dependency on my CSS library Moss for color-scheme awareness. See the Moss docs for its usage.

A dependency-free version of the initial theme is provided, but note that the colors are staticly defined instead of using Moss' style variables. They use light-dark() which means they're hardcoded to the inferred color-scheme, rather than being settable by a user option unlike the Moss version.

// no dependencies:
import '@ryanatkn/fuz_code/theme_standalone.css';

Modules

I encourage you to poke around src/lib if you're interested in using fuz_code.

Grammars

Enabled by default:

More

Docs are a work in progress:

Please open issues if you need any help.

Todo

  • add builtin grammars for markdown and regexp
  • lazy load the builtin grammars in Code.svelte
  • improve the default theme colors
  • add more themes
  • add a Vite plugin to do syntax styling at build-time for static cases
  • add a worker helper module
  • add some useful plugins, flesh out the API (start with line emphasis)
  • improve the TypeScript grammar to tokenize types
  • improve the grammars in subtle ways

Benchmarks

Performance is a high priority to best support runtime usage. This project is still early and there are more gains to be had.

Note that this benchmark is somewhat unfair to Shiki because it's not designed for runtime usage, and it probably does a significantly better job at the task at hand because it uses TextMate grammars.

Results styling the Svelte sample:

| Task name | Throughput average (ops/s) | Throughput median (ops/s) | Samples | | ----------------------- | -------------------------- | ------------------------- | ------- | | syntax_styler.stylize | 3149 ± 0.56% | 3333 | 6004 | | Prism.highlight | 2748 ± 0.51% | 2500 | 5293 | | Shiki engine/javascript | 69 ± 0.59% | 69 | 138 | | Shiki engine/oniguruma | 41 ± 0.27% | 40 | 82 |

Directly runnable benchmarks are not included yet - I don't know if I'll add them here or make a separate project.

To run the benchmarks yourself:

npm i -D shiki prismjs prism-svelte @types/prismjs @ryanatkn/fuz_code

Then add this file and import it somewhere like $routes/+page.svelte:

// $lib/benchmark.ts

import {Bench} from 'tinybench';
import Prism from 'prismjs';
import 'prism-svelte';
import {createHighlighterCoreSync} from 'shiki/core';
import {createJavaScriptRegexEngine} from 'shiki/engine/javascript';
import svelte_shiki from 'shiki/langs/svelte.mjs';
import nord from 'shiki/themes/nord.mjs';
import {createOnigurumaEngine} from 'shiki/engine/oniguruma';

import {syntax_styler} from '$lib/index.js';
import {sample_svelte_code} from '$lib/code_sample_inputs.js';

console.log('benchmarking');
const bench = new Bench({name: 'syntax styling', time: 2000});

const shiki_highlighter_js = createHighlighterCoreSync({
	themes: [nord],
	langs: [svelte_shiki],
	engine: createJavaScriptRegexEngine(),
});

const shiki_highlighter_builtin = createHighlighterCoreSync({
	themes: [nord],
	langs: [svelte_shiki],
	engine: await createOnigurumaEngine(import('shiki/wasm')),
});

bench
	.add('syntax_styler.stylize', () => {
		syntax_styler.stylize(sample_svelte_code, 'svelte');
	})
	.add('Prism.highlight', () => {
		Prism.highlight(sample_svelte_code, Prism.langs.svelte, 'svelte');
	})
	.add('Shiki engine/javascript', () => {
		shiki_highlighter_js.codeToHtml(sample_svelte_code, {lang: 'svelte', theme: 'nord'});
	})
	.add('Shiki engine/oniguruma', () => {
		shiki_highlighter_builtin.codeToHtml(sample_svelte_code, {lang: 'svelte', theme: 'nord'});
	});

await bench.run();

console.log(bench.name);
console.table(bench.table());

License 🐦

based on Prism by Lea Verou

the Svelte grammar is based on prism-svelte by @pngwn

MIT