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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@khotwa/jana

v0.2.0

Published

Vite plugin for Markdown with Svelte component support and unified plugins

Readme

Jana

A Vite plugin that transforms Markdown files into HTML, allowing you to import and use Svelte components directly in your Markdown content. Extensible with remark and rehype plugins.

Features

  • Import Svelte components inside Markdown files - Use Svelte components directly in your Markdown content
  • Prose components - Auto-replace HTML tags (<p>, <h1>, <pre>, etc.) with your custom Svelte components
  • Automatic escaping of Svelte syntax ({, }) in code blocks
  • Full Markdown to HTML conversion
  • Extensible with remark and rehype plugins
  • Fast and lightweight (no syntax highlighting overhead)
  • SvelteKit and Vite compatible

Installation

npm install @khotwa/jana

Usage

Basic Setup

1. Add Jana to Vite Config

Add Jana to your vite.config.js or vite.config.ts:

import { defineConfig } from 'vite'
import { jana } from '@khotwa/jana'

export default defineConfig({
  plugins: [
    jana()
    // ... other plugins
  ]
})

2. Configure Svelte Extensions

Add .md to the extensions in your svelte.config.js:

const config = {
  extensions: ['.svelte', '.md']
  // ... rest of your config
}

Using Markdown Files

Option 1: Import as a Component

Import Markdown files directly as Svelte components:

<script>
  import Post from './Post.md'
</script>

<Post />

Option 2: Use as SvelteKit Route File

In SvelteKit, you can use Markdown files directly as route pages:

src/routes/blog/+page.md

The Markdown file will be automatically processed and rendered as a Svelte page when accessed via the route.

Using Svelte Components in Markdown

You can import and use Svelte components directly inside your Markdown files:

<script>
  import MyComponent from './MyComponent.svelte'
</script>

# My Blog Post

This is regular markdown content.

<MyComponent />

You can use components anywhere in your markdown!

Prose Components

Prose components let you replace standard HTML tags with your own Svelte components. For example, you can replace every <p> with a custom <P> component that adds styling, or every <pre> with a <Pre> component that adds a copy button.

Auto-Scan (default)

By default, Jana scans src/lib/components/prose/ for Svelte files that match known HTML tag names:

src/lib/components/prose/
  P.svelte      → wraps all <p> tags
  H1.svelte     → wraps all <h1> tags
  Pre.svelte    → wraps all <pre> tags
  Code.svelte   → wraps all <code> tags
  A.svelte      → wraps all <a> tags

Just create the file and Jana picks it up automatically. No config needed.

Supported tag names: A, Blockquote, Code, Em, H1-H6, Hr, Img, Li, Ol, P, Pre, Strong, Table, Tbody, Td, Th, Thead, Tr, Ul.

Custom Prose Directory

Change the scan directory with the prose option:

jana({
  prose: 'src/components/prose'
})

Explicit Components

Map HTML tags to specific component paths directly:

jana({
  components: {
    p: '$lib/components/P.svelte',
    pre: '$lib/components/CodeBlock.svelte',
    h1: '$lib/components/Heading.svelte'
  }
})

Explicit components override auto-scanned ones, so you can use both — auto-scan for most tags and explicit config for specific overrides.

Code Block Metadata

When you use a prose component for pre, Jana automatically passes code block metadata as props:

```js title="example.js" highlight
console.log('hello')
```

Your Pre.svelte component receives:

<script>
  let { lang, title, highlight, children } = $props()
  // lang = "js", title = "example.js", highlight = true
</script>

Advanced Usage

Custom Unified Plugins

Jana supports adding custom remark and rehype plugins to extend functionality:

import { defineConfig } from 'vite'
import { jana } from '@khotwa/jana'
import remarkGfm from 'remark-gfm'
import rehypeShiki from 'rehype-shiki'

export default defineConfig({
  plugins: [
    jana({
      plugins: {
        remark: [remarkGfm],
        rehype: [[rehypeShiki, { theme: 'github-dark' }]]
      }
    })
  ]
})

Plugin format:

  • Plugins can be passed as a function: [remarkGfm]
  • Or as a tuple with options: [[rehypeSlug, { prefix: "heading-" }]]

Full Configuration

jana({
  // Custom prose directory (default: 'src/lib/components/prose')
  prose: 'src/lib/components/prose',

  // Explicit component mappings (override auto-scanned ones)
  components: {
    pre: '$lib/components/CodeBlock.svelte'
  },

  // Custom unified plugins
  plugins: {
    remark: [remarkGfm],
    rehype: [rehypeSlug]
  }
})

How It Works

Jana uses the unified ecosystem to process Markdown:

  1. Parse — Converts Markdown to an abstract syntax tree (AST) with remark-parse
  2. Unwrap — Lifts Svelte components out of <p> wrappers (remark treats them as inline)
  3. Collect metadata — Extracts code block meta (lang, title, etc.) for prose components
  4. User remark plugins — Runs any custom remark plugins
  5. Transform — Converts the Markdown AST to HTML AST with remark-rehype
  6. User rehype plugins — Runs any custom rehype plugins
  7. Wrap elements — Replaces matched HTML tags with Svelte component wrappers
  8. Escape — Escapes Svelte syntax characters ({, }) in code blocks
  9. Stringify — Converts the AST to an HTML string

The plugin automatically processes any file ending with .md during Vite's build process.

License

MIT