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

@libaro-io/libaro-utilities

v2.0.2

Published

A set of UI composables and developer tooling (incl. Laravel translation enforcement) for Libaro JavaScript applications.

Readme

LIBARO LOGO

A set of UI composables and developer tooling for Libaro JavaScript applications.

  • Laravel translation enforcement — Vite plugin + typed getTrans / getTransChoice helpers, fully auto-generated from your lang/ directory.
  • Tailwind v4 reference plugin — auto-injects @reference into every Vue SFC <style> block.

Installation

npm install --save-dev @libaro-io/libaro-utilities

Peer dependencies

The package generates code that imports from laravel-vue-i18n and vue, and the Vite plugin runs inside Vite. Make sure these are installed in your project:

npm install laravel-vue-i18n vue
npm install --save-dev vite

| Peer | Required for | Range | |---|---|---| | laravel-vue-i18n | The generated getTrans runtime | ^2.0.0 \|\| ^3.0.0 | | vue | The reactive wGetTrans / wGetTransChoice (uses ComputedRef) | ^3.0.0 | | vite | The translationEnforcer plugin (optional) | ^4 \|\| ^5 \|\| ^6 |


Laravel translation enforcement

A Vite plugin that scans your Laravel lang/ directory and emits one self-contained TypeScript file containing:

  • a literal-union TranslationKey type (compile-time autocompletion + type-checking),
  • a runtime Set of valid keys (dev-time warning when a key drifts), and
  • ready-to-use getTrans / getTransChoice / wGetTrans / wGetTransChoice functions bound to laravel-vue-i18n.

You add the plugin to vite.config.ts, import what you need from @/translations anywhere in your app, and that's it.

1. Register the Vite plugin

// vite.config.ts
import {defineConfig} from "vite";
import {translationEnforcer} from "@libaro-io/libaro-utilities/vite";

export default defineConfig({
    plugins: [
        translationEnforcer(),
    ],
});

That's the zero-config form. All options are optional — defaults shown below:

translationEnforcer({
    langDir: "lang",                         // Laravel lang directory
    output: "resources/js/translations.ts",  // Single .ts file to emit
    typeName: "TranslationKey",              // Name of the exported type
    extensions: [".php", ".json"],           // Pass [".php"] for PHP-only projects
});

The plugin runs on buildStart and re-runs in dev whenever a file under langDir changes. Make sure to add the output path to your .gitignore — the file is regenerated on every dev/build.

2. Use the helpers in your app

The generated file exports four functions. Pick the one that matches your context:

<script setup lang="ts">
import {getTrans, getTransChoice, wGetTrans, wGetTransChoice} from "@/translations";
import {ref, computed} from "vue";

// 1. Singular, non-reactive — for one-shot calls and templates
const buttonLabel = getTrans("auth.login");

// 2. Plural, non-reactive — Laravel pipe syntax, e.g.
//    'apples' => '{0} No apples|{1} One apple|[2,*] :count apples'
const itemCount = ref(5);
const itemLabel = computed(() =>
    getTransChoice("registrations.items", itemCount.value, {count: itemCount.value}),
);

// 3. Singular, reactive — auto-updates when the active locale changes
const pageTitle = wGetTrans("pages.dashboard.title");

// 4. Plural, reactive — combines (2) and (3)
const messageCount = ref(0);
const messageLabel = wGetTransChoice("inbox.messages", messageCount.value, {count: messageCount.value});
</script>

<template>
    <h1>{{ pageTitle }}</h1>
    <button>{{ buttonLabel }}</button>
    <p>{{ itemLabel }}</p>
    <p>{{ messageLabel }}</p>
</template>

When to use which variant

| Function | Returns | Use when | |---|---|---| | getTrans | string | One-shot translation, template binding, no reactivity needed | | getTransChoice | string | Same as above, but with pluralisation (count parameter) | | wGetTrans | ComputedRef<string> | The result feeds a computed/ref, and users can switch locale at runtime | | wGetTransChoice | ComputedRef<string> | Reactive + plural |

TypeScript refuses any key that isn't in the generated union. In dev mode a console warning fires if a key was removed from lang/ but is still referenced somewhere in your app.

Supported lang/ layouts

  • lang/<locale>.json — Laravel 9+ JSON translations. The JSON keys themselves become translation keys.
  • lang/<locale>/<file>.php with return [ ... ] arrays — keys are namespaced as <file>.<key>.
  • Nested subdirectories under a locale: lang/en/admin/users.phpadmin/users.<key>.
  • Nested PHP arrays — flattened with dot notation: 'user' => ['name' => '...']user.name.

Generated file — .gitignore

The output file is regenerated on every dev/build, so it belongs in .gitignore. Add:

# Auto-generated by @libaro-io/libaro-utilities
/resources/js/translations.ts

(Or whatever path you configured in output.)

Advanced: custom translator without the plugin

If you can't use the Vite plugin (different bundler, special wiring), createGetTrans is also exported for manual composition:

import {createGetTrans} from "@libaro-io/libaro-utilities";
import {trans} from "laravel-vue-i18n";

const VALID_KEYS = ["auth.failed", "auth.login"] as const;
type MyKey = typeof VALID_KEYS[number];

export const getTrans = createGetTrans<MyKey, typeof trans>({
    keys: VALID_KEYS,
    translate: trans,
    warnOnMissing: import.meta.env.DEV,
});

This is intentionally low-level; the Vite plugin path above is the recommended approach for 99% of projects.


Tailwind v4 reference plugin

// vite.config.ts
import {tailwindReferencePlugin} from "@libaro-io/libaro-utilities";

export default defineConfig({
    plugins: [tailwindReferencePlugin()],
});

Injects @reference "@css/app.css"; at the top of every <style> block in .vue SFCs so Tailwind v4 utilities resolve correctly in scoped styles.

Override the reference line if your CSS lives elsewhere:

tailwindReferencePlugin({referenceLine: '@reference "@/styles/app.css";'});

Libaro

This package is created by Libaro and is free to use.