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

astro-awaited

v0.0.471

Published

An Astro integration that enables you to render fallback placeholders while server-side data is being fetched

Readme

✨ Features

  • 🚀 Zero JavaScript (Modern Browsers)
    Emulates React’s Suspense behavior—even with JavaScript disabled.

    • JavaScript is required for smooth exit transitions when using Astro’s View Transitions (ClientRouter).
    • JavaScript is required to polyfill behavior on legacy browsers.
  • 🎯 Zero Configuration
    Works out of the box with sensible defaults.

  • 🔧 Customizable Transitions
    Configure transition duration and easing for awaited components.

  • 📦 TypeScript Support
    Full type definitions included.

  • Fast Build-Time Performance
    Minimal overhead with efficient AST transformations.

📋 Requirements

  • HTML Streaming must be enabled on the server.
    Without streaming, this integration won’t work.

  • Astro v4.0.0+ and Node.js v18+

⚠️ Limitations

Even though astro-awaited is designed to be intuitive, there are a few important caveats and best practices to keep in mind:

  • ⚠️Works Only with .astro Components Awaited is compatible only with .astro components. You can nest it inside an Astro Island to enable hydration later, but:

    • The Awaited component itself must remain in a .astro file
    • Do not use the client:only directive, as it disables server-side rendering and breaks HTML streaming
  • 🧱 Streaming is top-to-bottom:
    Each awaited component blocks the stream until its data is fetched. Structure your layout to avoid bottlenecks.

  • Don’t Fetch in Page Frontmatter:
    Fetching data in the page frontmatter blocks the entire page from rendering, including fallbacks. Instead, move fetch logic into individual components to leverage streaming effectively.
    Learn more in Astro’s official guide.

  • 🚫 No HOC (Higher-Order Components):
    Astro Awaited relies on HTML streaming and Astro’s slot feature. Wrapping awaited logic in a separate component will break fallback behavior.

❌ Incorrect Usage

---
// ResultsListAwaited.astro
import { Awaited, Fallback } from 'astro-awaited/components';
import ResultsList from './ResultsList.astro';
---

<Awaited>
  <ResultsList query={searchQuery} page={searchPage} />
  <Fallback>
    <p>Loading...</p>
  </Fallback>
</Awaited>
---
// index.astro
import ResultsListAwaited from './ResultsListAwaited.astro';
---

<Layout>
  <h1>My results list</h1>
  <ResultsListAwaited />
</Layout>

This won’t work—Astro will treat ResultsListAwaited as an async component and begin fetching before rendering its children.

✅ Correct Usage

---
// index.astro
import { Awaited, Fallback } from 'astro-awaited/components';
import ResultsList from './ResultsList.astro';
---

<Layout>
  <h1>My results list</h1>
  <Awaited>
    <ResultsList query={searchQuery} page={searchPage} />
    <Fallback>
      <p>Loading...</p>
    </Fallback>
  </Awaited>
</Layout>

Use Awaited declaratively, directly in your page layout.

📦 Installation

npm install astro-awaited

🚀 Usage

1. Add the integration to your Astro config

// astro.config.mjs
import { defineConfig } from "astro/config";
import awaited from "astro-awaited";

export default defineConfig({
  integrations: [awaited()],
});

2. Use Awaited and Fallback in your components

---
// SearchPage.astro
import { Awaited, Fallback } from 'astro-awaited/components';
import ResultsList from './ResultsList.astro';
---

<Awaited>
  <ResultsList query={searchQuery} page={searchPage} />
  <Fallback>
    <p>Loading...</p>
  </Fallback>
</Awaited>

⚙️ Components

<Awaited />

The Awaited component provides a graceful fallback mechanism for Astro pages during navigation transitions. It ensures that fallback content is displayed only when the awaited content is not yet ready, and automatically cleans up after route changes.

🧩 Props

| Prop | Type | Default | Description | | -------------------- | ------------------------------------------------------ | ----------- | ------------------------------------------------------------------------------- | | transitionDuration | number | 200 | Duration (in ms) for the fallback transition animation. | | transitionEase | "linear" \| "ease-in" \| "ease-out" \| "ease-in-out" | "linear" | CSS easing function for the fallback transition. | | contentProps | HTMLAttributes<'div'> | undefined | Props passed directly to the inner content container (data-awaited-content). | | ...rest | HTMLAttributes<'div'> | — | Any additional props are applied to the outer wrapper (data-awaited-wrapper). |

🎬 Behavior

  • Automatic Cleanup: On route transitions, the component removes any lingering awaited content to prevent duplication.
  • Fallback Visibility: If the awaited content is empty or not yet rendered, the fallback remains visible. Once content is detected, the fallback fades out smoothly.
  • CSS Fallback: If :has() is unsupported by the browser, the component manually toggles fallback visibility using JavaScript.

🎨 Styling

The component uses CSS variables for animation control:

--animationDuration: ${transitionDuration}ms;
--animationEase: ${transitionEase};

These are applied to the fallback element for smooth transitions.

<Fallback />

The <Fallback> component defines the placeholder UI shown while awaited content is loading or unavailable. It’s designed to be slotted into the <Awaited> component using the fallback slot, and it automatically transitions out once the awaited content becomes visible.

📦 Usage

<Awaited>
  <Fallback>
    <div class="spinner" />
  </Fallback>

  <div>
    <!-- Your awaited content here -->
  </div>
</Awaited>

You can also use any custom markup inside <Fallback>—it’s just a semantic wrapper to help with styling and behavior.

🎯 Purpose

  • Acts as a visual placeholder while data or content is being fetched.
  • Automatically fades out when awaited content becomes available.
  • Integrates seamlessly with the Awaited component’s transition system.

🛠️ How It Works

Astro Awaited uses a Vite plugin during build time to:

  1. Parse .astro files via the Astro compiler.
  2. Detect Fallback components missing a slot attribute.
  3. Automatically inject slot="fallback" into those components.
  4. Return the transformed code.

✅ All transformations happen at build time—no runtime overhead.

📄 License

MIT

🤝 Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.