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 🙏

© 2025 – Pkg Stats / Ryan Hefner

fey-script

v0.1.3

Published

Parser and runtime for Fey Script - a homebrew scripting language for fantasy content.

Downloads

8

Readme

Fey-Script

Fey-Script is a superset of the well known markdown language created to write interactive documents for TTRPGs (Tabletop Roleplaying Games).

Fey-Script will highlight typical dice notation like 2d6+2 and can "roll" those dice for you. Input fields allow you to create custom character sheets either for less supported Systems or your homebrew.

Conditional blocks make it possible to write character creation guides where rules and generator merge into one.

Powerful but simple structual elements allow you to display your document in the most efficient way possible.

You can join the Discord to get in touch.

Usage

Fey-Script uses Webcomponent technologie. Simple import the script either by adding a script-tag or by importing it into your bundle and you'll be able to use the fey-viewer tag.

<html>
<body>
    <fey-viewer id="viewer">
        # Fey-Script code
        All text placed here will be renderered as Fey-Script
    </fey-viewer>
    <script src="fey-script.js"></script>
    <script>
        const viewer = document.getElementById('viewer');
        viewer.resolveImports = async (path) => path.fileContent;
        viewer.addEventListener('onDiceRoll', (e) => {
            alert(e.detail.result.output);
        });
        viewer.addEventListener('change', (e) => {
            console.log(e.detail); // contains all data of the viewer
        });
    </script>
</body>
</html>

Resolving imports

Since Fey-Script can be used in many different applications you'll have to supply a resolver function if you want to support imports in your script. A resolver function is an asynchron function taking a string (the path to import) and returning a string (the content of the imported file).

Depending on your use case this could use local files, Web-URLs or a simple object storing strings to resolve your imports.

const importables = {
    greeting: '# Hello World'
}
const viewer = document.getElementById('viewer');
viewer.resolveImports = async (path) => importables[path];

Event Listeners

onDiceRoll

This event is triggered when a dice notation link is clicked within the document. It'll contain a dice result generated by https://github.com/dice-roller/rpg-dice-roller

viewer.addEventListener('onDiceRoll', (e) => {
    alert(e.detail.result.output);
});

change

This event is triggered when any input within the document triggers a change event. It'll contain all the data currently used by the viewer.

viewer.addEventListener('change', (e) => {
    console.log(e.detail); // contains all data of the viewer
});

Fey-Script Syntax

Markdown

Use the well known markdown syntax to style your text, add tables and images and much more.

Front matter

You can define data at the beginning of your document to be used with it. To do so write YAML code between two lines with three dashes. This block needs to be at the very top of your document.

---
info: Use "front matter" to supply initial data to your document
name: Nira
str: 10
dex: 15
con: 8
int: 10
wis: 14
cha: 12
---

Structual Elements

You can wrap your markdown syntax in different containers to change how they are displayed.

HTML

You can write HTML code within Fey-Script. While Fey-Script comes with a bunch of useful tools and shortcuts if you know your way around the HTML and CSS languages you can include them in Fey-Script to achieve even more. Keep in mind though that Fey-Script within HTML-Elements won't be parsed automatically.

<div style="background-color: darkmagenta; padding: 1rem;">
  Some text on dark magenta background that can't be __bold__ because Fey-Script and markdown don't work within HTML.
</div>

Card

Cards are small boxes that seperate their content from the rest of the document. They're great to give a preview or a small overview or put focus on something important. You can create a card by using double square brackets

[[
  ### Card
  This is the content of the card. It can be any valid fey-script code.
]]

Row

The row will display contained elements next to each other with a bit of spacing and break automatically into the next row if no more space is available.

  :::row
    [[
      ### First Card
      This card contains some test text.
    ]]
    [[
      ### Second Card
      This card contains some test text.
    ]]
  :::

Grid

Using the grid container you can define columns with relative sizes. In this example a grid of 1-2-1 is used which means the center column is twice as wide as the outer ones. You can use as many columns as you like so 1-1-1-1-1-1-1 would give you seven columns of equal size.

:::grid-1-2-1
<div style="background-color: darkcyan; padding: 1rem">

</div>
<div style="background-color: darkblue; padding: 1rem">

</div>
<div style="background-color: darkmagenta; padding: 1rem">

</div>
:::

Interactive Elements

You can use inputs and variables to control the rendering of your document. Using double curly brackets you can output any value within the document.

{{name}}

Inputs

Inputs are defined by writing "i" followed by a variable name in square brackets. They allow you to edit variables on the fly and the document will react to the changes. You can provide optional settings to your input by writing them in JSON format after a |. Most attributes of HTML input elements are supported as well as a "label" attribute to override the label that will be automatically generated. The default type for inputs is number.

i[name|{"type":"text"}]

Selects

Selects work just like inputs but give the user a list of available values to choose from instead.

s[className][
  Warrior
  Rogue
  Mage
]

Conditional Block

It's possible to wrap parts of your document in a conditional if block. The wrapped content will only be shown when the condition is met. Conditions are written as Javascript.

:::if className === "Warrior"
You choose the Warrior class. You are strong and know how to fight.
:::

:::if className === "Rogue"
You choose the Rogue class. You are sneaky and know how to get out of sticky situations.
:::

:::if className === "Mage"
You choose the Mage class. You are intelligent and know how to cast magic
:::

Dice Notation

When writing text it'll be scanned for dice notation like +5, 2d6+2 or 1d4. Text like this will be highlighted like a link and can be clicked to generate dice results for the given notation.

No special code needed. +5, 2d6+2 or 1d4 and others will just work.

DnD Stats

Fey-Script comes with a shortcut to calculate DnD attribute modifiers. You'd be able to calculate them just fine using the curly brackets but your document would get quite long. Write $mod and pass a variable name in round brackets to calculate the DnD Modifier.

|                |               |               |               |               |               |
|----------------|---------------|---------------|---------------|---------------|---------------|
| i[str]         | i[dex]        | i[con]        | i[int]        | i[wis]        | i[cha]        |
| {{$mod(str)}}  | {{$mod(dex)}} | {{$mod(con)}} | {{$mod(int)}} | {{$mod(wis)}} | {{$mod(cha)}} |

Tabs

Tabs are a great way to group information and hide things that rarely come into play away from the spotlight while still having it accessible.

|-- Tab One ---
|
| Tabs are great! I want to see this information most of the time!
|
|-- Tab Two ---
|
| But sometimes this information is required so I just switch over here.
|
|---

Images

You can use images within Fey-Script just like in regular Markdown but there is an additional feature to crop your images. Keep in mind that the actual file size doesn't change using this feature and it only affects how images are displayed.

Regular display of an image
![image](fireball.png)

The image will be displayed with a width of 300px. It's height will adjust to keep the original aspect ratio.
![image](fireball.png?width=300px)

The image will be displayed with a height of 300px. It's width will adjust to keep the original aspect ratio.
![image](fireball.png?height=300px)

The image will be displayed with width of 300px and height of 100px.
![image](fireball.png?width=300px&height=100px)

The image will be displayed with a ratio of 16:9 cropping parts of the image around the center.
![image](fireball.png?aspectRatio=16/9)

The image will be display in portrait mode focusing on the top left and cropping the bottom right.
![image](fireball.png?aspectRatio=2/3&focus=top left)

Imports

You can import Fey-Script files into your document a few different ways. Using curly brackets and the ">" sign will import the content of the given file and insert it straight into your document. If you're using square brackets instead, you'll create a card that will display the first headline of the imported file as title, the first image as an image and look for the key "description" in the frontmatter data to display it on the card.

{{> text }}

[[> fireball ]]