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

http-resources-slice

v0.1.0

Published

Zero-dependency, framework-agnostic HTTP resource management with optimistic updates

Readme

http-resources-slice

npm version npm downloads bundle size license

Zero-dependency, framework-agnostic HTTP resource management with optimistic updates

A lightweight TypeScript library that generates type-safe CRUD operations with built-in loading states, error handling, and optimistic UI updates. Works with any state management solution that follows the Zustand pattern.

✨ Features

  • 🚀 Zero Dependencies - No runtime dependencies, just pure TypeScript
  • 🔌 Framework Agnostic - Works with Zustand, Valtio, or any state manager using (set, get) pattern
  • 🤖 AI Agent Ready - Simple, predictable API perfect for AI code generation and autonomous agents
  • Optimistic Updates - Built-in support for optimistic UI with automatic rollback on failure
  • 🎯 Type Safe - Full TypeScript support with inferred types
  • 🔄 CRUD Operations - Auto-generated fetch, create, update, patch, and delete functions
  • 📡 Request Cancellation - Cancel in-flight requests to prevent memory leaks
  • 🔍 Query Parameters - Easy query parameter support for filtering and pagination
  • 🛡️ Error Handling - Comprehensive error states per operation
  • 📊 Loading States - Individual loading states for each operation

📦 Installation

npm install http-resources-slice
# or
yarn add http-resources-slice
# or
pnpm add http-resources-slice

🚀 Quick Start

Basic Usage with Zustand

import { create } from 'zustand';
import { createHttpResources } from 'http-resources-slice';

type User = {
  id: number;
  name: string;
  email: string;
};

const useStore = create((set, get) => ({
  ...createHttpResources('user')(set, get),
}));

// Usage in components
function UserProfile() {
  const { user, fetchUser, postUser, putUser, delUser, userLoading, userError } = useStore();
  
  // Fetch all users
  await fetchUser();
  
  // Create a new user
  await postUser({ name: 'John', email: '[email protected]' });
  
  // Update a user
  await putUser(1, { name: 'John Doe', email: '[email protected]' });
  
  // Delete a user
  await delUser(1);
}

With Optimistic Updates

const useStore = create((set, get) => ({
  ...createHttpResources('user', { isOptimistic: true })(set, get),
}));

// Optimistic updates automatically update state before API confirms
// and rollback on error
await postUser({ name: 'John', email: '[email protected]' });

With Base URL and Options

const useStore = create((set, get) => ({
  ...createHttpResources('user', {
    baseUrl: '/api/v1',
    include: ['fetch', 'post', 'del'], // Only include specific methods
    fetchOptions: {
      headers: {
        'Authorization': 'Bearer token',
      },
    },
  })(set, get),
}));

📖 API Reference

createHttpResources(name, options?)

Creates a resource slice with CRUD operations.

Parameters

| Name | Type | Description | |------|------|-------------| | name | string | Resource name (e.g., 'user', 'product') | | options | CreateResourcesOptions | Optional configuration |

Options

type CreateResourcesOptions = {
  /**
   * HTTP methods to include
   * - "all": includes all CRUD methods (default)
   * - Array: specific methods to include
   */
  include?: "all" | Array<"fetch" | "post" | "put" | "patch" | "del">;
  
  /**
   * Base URL prefix for all requests (e.g., "/api")
   * @default ""
   */
  baseUrl?: string;
  
  /**
   * Enable optimistic updates for POST, PUT, PATCH
   * @default false
   */
  isOptimistic?: boolean;
  
  /**
   * Default fetch options applied to all requests
   */
  fetchOptions?: Omit<RequestInit, "method" | "body" | "headers"> & {
    headers?: Record<string, string>;
  };
};

Returns

An object with the following properties (using 'user' as example name):

| Property | Type | Description | |----------|------|-------------| | user | TData \| null | Current data | | setUser | (data) => void | Manual data setter | | fetchUser | (params?) => Promise<TData[]> | Fetch all items | | postUser | (body, options?) => Promise<TData> | Create new item | | putUser | (id, body, options?) => Promise<TData> | Replace item | | patchUser | (id, body, options?) => Promise<TData> | Partial update | | delUser | (id) => Promise<void> | Delete item | | cancelFetchUser | () => void | Cancel fetch request | | cancelPostUser | () => void | Cancel post request | | cancelPutUser | () => void | Cancel put request | | cancelPatchUser | () => void | Cancel patch request | | cancelDelUser | () => void | Cancel delete request | | fetchUserLoading | boolean | Fetch loading state | | fetchUserError | Error \| null | Fetch error state | | postUserLoading | boolean | Post loading state | | postUserError | Error \| null | Post error state | | ... | ... | Similar for put, patch, del |

🤖 AI Agent Integration

This library is designed with AI agents in mind:

Why It's AI-Friendly

  1. Predictable Naming - Consistent pattern: {method}{ResourceName}
  2. Self-Documenting - Function names describe their purpose
  3. Type Inference - AI can infer types from minimal context
  4. No Hidden State - All state is explicit and accessible
  5. Standard HTTP - Uses familiar REST conventions

Example: AI-Generated Code

// AI can easily generate this pattern:
const { 
  products, 
  fetchProducts, 
  postProducts, 
  productsLoading, 
  productsError 
} = useStore();

// Clear, predictable, no surprises

🔧 Advanced Usage

Query Parameters

// Fetch with filters
await fetchProducts({ category: 'electronics', minPrice: 100 });

// POST with query params
await postProduct(data, { query: { source: 'import' } });

// PUT with query params
await putProduct(id, data, { query: { version: 2 } });

Multiple Resources

const useStore = create((set, get) => ({
  ...createHttpResources('user')(set, get),
  ...createHttpResources('product')(set, get),
  ...createHttpResources('order')(set, get),
}));

Custom State Management

Works with any state manager following the (set, get) pattern:

// Custom store implementation
function createCustomStore() {
  let state = {};
  const listeners = new Set();
  
  const set = (updater) => {
    state = typeof updater === 'function' ? updater(state) : { ...state, ...updater };
    listeners.forEach(fn => fn(state));
  };
  
  const get = () => state;
  
  return { set, get, subscribe: (fn) => listeners.add(fn) };
}

const { set, get } = createCustomStore();
const userResource = createHttpResources('user')(set, get);

Error Handling

try {
  await postUser({ name: 'John' });
} catch (error) {
  console.error('Failed to create user:', error);
}

// Or use error state
const { userError } = useStore();
if (userError) {
  console.error(userError.message);
}

Request Cancellation

// Start a request
fetchUsers();

// Cancel it if needed (e.g., component unmount)
cancelFetchUsers();

📊 Comparison

| Feature | create-http-resources-slice | React Query | SWR | RTK Query | |---------|----------------------------|-------------|-----|-----------| | Dependencies | 0 | ~13kb | ~6kb | ~20kb | | Framework | Any | React | React | Redux | | Bundle Size | ~2kb | Large | Medium | Large | | Learning Curve | Minutes | Hours | Hours | Days | | AI-Friendly | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |

🎯 Use Cases

✅ Perfect For

  • Micro-frontends needing lightweight HTTP management
  • AI-generated code and autonomous agents
  • Projects prioritizing minimal dependencies
  • Custom state management solutions
  • Server-side rendering (SSR) applications
  • Non-React frameworks (Vue, Svelte, Solid, etc.)

❌ Not For

  • Applications needing advanced caching strategies
  • Projects requiring offline-first architecture
  • Complex data synchronization scenarios
  • GraphQL APIs (use GraphQL-specific solutions)

📝 Examples

E-commerce Product Management

type Product = {
  id: number;
  name: string;
  price: number;
  stock: number;
};

const useProductStore = create((set, get) => ({
  ...createHttpResources<Product>('product', {
    baseUrl: '/api/shop',
    isOptimistic: true,
  })(set, get),
}));

// Usage
const { 
  products, 
  fetchProducts, 
  postProducts, 
  patchProducts,
  productsLoading 
} = useProductStore();

await fetchProducts({ category: 'electronics' });
await postProducts({ name: 'New Product', price: 99.99, stock: 100 });
await patchProducts(1, { stock: 95 }); // Optimistic update

User Authentication

type Session = {
  user: { id: number; name: string };
  token: string;
};

const useAuthStore = create((set, get) => ({
  ...createHttpResources<Session>('session', {
    baseUrl: '/api/auth',
    fetchOptions: {
      credentials: 'include',
    },
  })(set, get),
}));

// Login
const { postSession } = useAuthStore();
await postSession({ email, password });

// Logout
const { delSession } = useAuthStore();
await delSession(currentSession.id);

🛠️ Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Build
npm run build

# Lint
npm run lint

# Format
npm run format

📄 License

MIT License - feel free to use in personal and commercial projects.

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📦 Package Size

  • Minified: ~2kb
  • Gzipped: ~1kb
  • Dependencies: 0

🔗 Related Resources


Built with ❤️ for the JavaScript community