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

@voidbase/foundation

v1.1.1

Published

A comprehensive utility library for Vue and Nuxt projects. Includes validation utilities, form/input components, localization support, and more. Make starting new projects easier with production-ready tools.

Downloads

372

Readme

Void Foundation

A comprehensive utility library for Vue and Nuxt projects. Make starting new projects easier with production-ready validation utilities, form/input components, and essential tools.

What's Included

Current Features

Validation Utilities - Composable validation with 30+ rules
HTTP Client - Universal HTTP client with interceptors, retry, and auth
Type Safety - 100% TypeScript with zero any types
Localization - Built-in support for 5 languages (en, es, fr, ar, ckb)
Extensible - Custom validators, transforms, and locales
Zero Dependencies - Lightweight and fast
Well Tested - 70+ passing tests

Coming Soon

🚧 Form Components - Ready-to-use form and input components for Vue/Nuxt
🚧 Additional Utilities - More helpers to accelerate project development


Installation

# Using bun
bun add @voidbase/foundation

# Using npm
npm install @voidbase/foundation

Quick Start

import { validate, string, number } from '@voidbase/foundation';

const schema = {
  username: string('Username').required().min(3).max(20),
  email: string('Email').required().email().lowercase(),
  age: number('Age').required().min(18).integer(),
};

const result = validate({
  username: 'john_doe',
  email: '[email protected]',
  age: 25,
}, schema);

if (result.valid) {
  console.log('✓ Valid:', result.data);
  // { username: 'john_doe', email: '[email protected]', age: 25 }
} else {
  result.errors.forEach(err => {
    console.log(`✗ ${err.field}: ${err.message}`);
  });
}

Why Void Foundation?

Composable & Intuitive

// ✅ Void Foundation - Fluent and readable
const email = string('Email')
  .required()
  .email()
  .lowercase()
  .trim();

// ❌ Traditional approach - Verbose object syntax
const email = {
  type: 'string',
  label: 'Email',
  required: true,
  isEmail: true,
  lowercase: true,
  trim: true,
};

Built-in Localization

import { setLocale } from '@voidbase/foundation';

// Switch to Spanish
setLocale('es');
// Error: "Email es requerido"

// Switch to French
setLocale('fr');
// Error: "Email est requis"

// Or use inline
validate(data, schema, { locale: 'es' });

Type-Safe by Design

interface UserData {
  name: string;
  email: string;
  age: number;
}

const result: ValidationResult<UserData> = validate(data, schema);

if (result.valid) {
  // result.data is fully typed as UserData
  const user: UserData = result.data;
}

Schema Builders

String Validation

import { string } from '@voidbase/foundation';

string('Email').required().email().lowercase();
string('Username').required().min(3).max(20).pattern(/^[a-zA-Z0-9_]+$/);
string('Password').required().min(8).strongPassword();
string('Website').url().trim();

Number Validation

import { number } from '@voidbase/foundation';

number('Age').required().min(18).max(120).integer();
number('Price').required().positive();
number('Rating').required().min(1).max(5);

Array Validation

import { array, string } from '@voidbase/foundation';

array(string().email(), 'Recipients').required().min(1).max(10);
array(string().min(2).max(20), 'Tags').min(1).max(5);

File Validation

import { file } from '@voidbase/foundation';

file('Avatar')
  .required()
  .maxSize(5, 'MB')
  .extensions(['jpg', 'jpeg', 'png'])
  .mimeTypes(['image/jpeg', 'image/png']);

Date Validation

import { date } from '@voidbase/foundation';

date('Birth Date').required().past();
date('Event Date').required().future();
date('Start Date').min(new Date('2024-01-01'));

Enum Validation

import { enumField } from '@voidbase/foundation';

enumField(['admin', 'user', 'moderator'], 'Role').required();
enumField(['active', 'inactive', 'pending'], 'Status');

Nested Objects

import { object, string } from '@voidbase/foundation';

const schema = {
  name: string('Name').required(),
  address: object({
    street: string('Street').required(),
    city: string('City').required(),
    zipCode: string('Zip').required().pattern(/^\d{5}$/),
  }, 'Address'),
};

HTTP Client

A universal HTTP client that works in both browser and server environments.

Basic Usage

import { http } from '@voidbase/foundation';

// GET request
const { data } = await http.get('/api/users');

// POST request
await http.post('/api/users', {
  name: 'John',
  email: '[email protected]'
});

// With options
await http.get('/api/users', {
  params: { page: 1, limit: 10 },
  timeout: 5000
});

Create Custom Instance

import { createHttpClient } from '@voidbase/foundation';

const api = createHttpClient({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'X-API-Key': 'your-api-key'
  }
});

await api.get('/users');  // https://api.example.com/users

Authentication

// Bearer token
await http.get('/api/protected', {
  auth: { type: 'bearer', token: 'your-jwt-token' }
});

// Basic auth
await http.get('/api/protected', {
  auth: { type: 'basic', username: 'user', password: 'pass' }
});

Interceptors

const api = createHttpClient({ baseURL: 'https://api.example.com' });

// Add auth token to all requests
api.interceptors.request.use({
  onRequest: (config) => ({
    ...config,
    headers: {
      ...config.headers,
      'Authorization': `Bearer ${getToken()}`
    }
  })
});

// Handle errors globally
api.interceptors.response.use({
  onResponseError: (error) => {
    if (error.status === 401) {
      redirectToLogin();
    }
    throw error;
  }
});

Retry Logic

// Simple retry (3 attempts, exponential backoff)
await http.get('/api/flaky', { retry: true });

// Advanced retry
await http.get('/api/flaky', {
  retry: {
    times: 5,
    delay: 1000,
    backoff: 'exponential',
    retryOn: [500, 502, 503, 504]
  }
});

Error Handling

import { http, isHttpError } from '@voidbase/foundation';

try {
  await http.get('/api/users');
} catch (error) {
  if (isHttpError(error)) {
    console.log('Status:', error.status);  // 404
    console.log('Code:', error.code);      // 'RESPONSE_ERROR'
    console.log('Data:', error.data);      // Response body
  }
}

Request Cancellation

import { createCancelToken } from '@voidbase/foundation';

const token = createCancelToken();

http.get('/api/data', { signal: token.signal });

// Cancel the request
token.cancel('User navigated away');

📖 Full HTTP Documentation


Real-World Examples

User Registration

const registrationSchema = {
  username: string('Username')
    .required()
    .min(3)
    .max(20)
    .pattern(/^[a-zA-Z0-9_]+$/),
  
  email: string('Email')
    .required()
    .email()
    .lowercase()
    .trim(),
  
  password: string('Password')
    .required()
    .min(8)
    .strongPassword(),
  
  confirmPassword: string('Confirm Password')
    .required()
    .custom((value, data) => {
      return value === data.password || 'Passwords must match';
    }),
  
  age: number('Age')
    .required()
    .min(18)
    .integer(),
};

Product Schema

const productSchema = {
  name: string('Product Name').required().min(3).max(100),
  description: string('Description').required().min(10).max(5000),
  price: number('Price').required().positive().min(0.01),
  quantity: number('Quantity').required().integer().min(0),
  category: enumField(['electronics', 'clothing', 'food'], 'Category').required(),
  tags: array(string().min(2).max(30), 'Tags').required().min(1).max(10),
};

Advanced Features

Custom Validators

const username = string('Username')
  .required()
  .custom((value) => {
    if (value.includes('admin')) {
      return 'Username cannot contain "admin"';
    }
    return true;
  });

Cross-Field Validation

const schema = {
  password: string('Password').required(),
  confirmPassword: string('Confirm Password')
    .required()
    .custom((value, data) => {
      return value === data.password || 'Passwords must match';
    }),
};

Conditional Validation

const schema = {
  accountType: enumField(['personal', 'business'], 'Account Type').required(),
  companyName: string('Company Name').when('accountType', {
    is: 'business',
    then: { required: true, minLength: 2 },
    otherwise: { required: false },
  }),
};

Transform Functions

const email = string('Email')
  .trim()
  .lowercase()
  .transform((value) => value.replace(/\+.*@/, '@'));

Validation Options

// Stop on first error
validate(data, schema, { abortEarly: true });

// Remove unknown fields
validate(data, schema, { stripUnknown: true });

// Allow unknown fields
validate(data, schema, { allowUnknown: true });

// Use specific locale
validate(data, schema, { locale: 'es' });

// Pass context to custom validators
validate(data, schema, { context: { userId: '123' } });

Localization

Built-in Languages

  • English (en) - Default
  • Spanish (es) - Complete
  • French (fr) - Complete
  • Arabic (ar) - Complete
  • Central Kurdish/Sorani (ckb) - Complete

Set Global Locale

import { setLocale } from '@voidbase/foundation';

setLocale('es'); // Spanish
setLocale('fr'); // French

Register Custom Locale

import { LocaleRegistry, setLocale } from '@voidbase/foundation';

LocaleRegistry.register('de', {
  required: ({ label }) => `${label} ist erforderlich`,
  invalidEmail: ({ label }) => `${label} muss eine gültige E-Mail sein`,
  minLength: ({ label, min }) => `${label} muss mindestens ${min} Zeichen lang sein`,
});

setLocale('de');

Helper Functions

Use validation helpers independently:

import {
  isEmail,
  isUrl,
  isStrongPassword,
  isInRange,
  isEmpty,
} from '@voidbase/foundation';

if (isEmail('[email protected]')) {
  console.log('Valid email');
}

if (isUrl('https://example.com')) {
  console.log('Valid URL');
}

if (isStrongPassword('SecurePass123!')) {
  console.log('Strong password');
}

Documentation


TypeScript Support

Fully typed with TypeScript:

import type {
  ValidationResult,
  ValidationSchema,
  FieldSchema,
  ValidatorOptions,
} from '@voidbase/foundation';

Development

# Install dependencies
bun install

# Run tests
bun test

# Watch mode
bun test --watch

# Coverage
bun test --coverage

# Type check
bun run type-check

# Build
bun run build:all

Browser Support

  • Modern browsers (ES2020+)
  • Node.js 18+
  • Bun 1.0+

Performance

  • Zero dependencies
  • Lightweight bundle size
  • Fast validation (optimized for performance)
  • Tree-shakeable exports

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.


License

MIT © Void Foundation Team


Support

For issues, questions, or contributions:


Changelog

v1.1.0

  • HTTP Client - Universal HTTP client (browser + server)
  • ✨ Request/Response interceptors
  • ✨ Automatic retry with exponential backoff
  • ✨ Bearer, Basic, and custom authentication
  • ✨ Request cancellation with AbortController
  • ✨ Polling and concurrent request helpers
  • ✨ 70+ passing tests

v1.0.0

  • ✨ Initial release
  • ✨ Composable schema builders
  • ✨ Built-in localization (en, es, fr, ar, ckb)
  • ✨ Full TypeScript support
  • ✨ 30+ validation rules
  • ✨ 36+ passing tests