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

my-constellation-bg

v1.3.0

Published

A realistic animated starfield background inspired by night sky photography, featuring dense stars with natural brightness distribution and shooting stars with varying speeds

Readme

Realistic Starfield Background

A beautiful, performant animated starfield background inspired by real night sky photography. Features dense stars with natural brightness distribution, subtle twinkling, and shooting stars with realistic varying speeds. Perfect for creating engaging hero sections, landing pages, or any web interface that needs a touch of cosmic elegance.

Version License

✨ Features

  • 🌟 Realistic Star Distribution - 800+ stars with natural brightness (70% dim, 20% medium, 7% bright, 3% very bright with glow)
  • Subtle Twinkling - Configurable twinkling effect that's not overdone
  • 💫 Bright Star Glow - Very bright stars feature a beautiful radial glow effect
  • ☄️ Varying Speed Meteors - Shooting stars with slow (40%), medium (40%), and fast (20%) speeds
  • 🎨 Star Color Variations - Subtle white, warm white, cool blue, and yellow tints
  • 📱 Responsive - Automatically adapts to canvas/window size with consistent star density
  • Lightweight - Pure vanilla JavaScript, no dependencies
  • 🎯 Easy Integration - Simple API, works with any framework
  • 🔧 Backward Compatible - Still exports ConstellationBackground for existing users

🆕 What's New in v1.3.0

  • Realistic Night Sky - Inspired by actual star photography
  • Natural Star Distribution - Most stars are dim and tiny, few are bright (like real night sky)
  • Slower Meteor Speeds - More realistic shooting star speeds:
    • Slow meteors (40%): Speed 2-3.5, long graceful trails
    • Medium meteors (40%): Speed 4-6, balanced appearance
    • Fast meteors (20%): Speed 8-12, quick streaks
  • Pure Black Background - Deep space black (#000000) by default
  • No Constellation Lines - Clean, realistic starfield appearance
  • New Methods: setOptions(), triggerMeteor() for dynamic control
  • Test Suite - Run npm test to verify installation

📦 Installation

npm install my-constellation-bg

🔧 Build & Test

# Build the package
npm run build

# Test the package (verify it works)
npm test

🚀 Usage Guide

Method 1: Vanilla HTML/JavaScript (Easiest)

Option A: Using Built File

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Starfield Background</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            overflow: hidden;
        }

        #starfield-canvas {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: -1;
        }

        .content {
            position: relative;
            z-index: 1;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100vh;
            flex-direction: column;
        }

        h1 {
            font-size: 4rem;
            margin-bottom: 1rem;
        }
    </style>
</head>
<body>
    <canvas id="starfield-canvas"></canvas>

    <div class="content">
        <h1>Welcome to My Site</h1>
        <p>Beautiful starfield background ✨</p>
    </div>

    <script src="dist/index.js"></script>
    
    <script>
        const canvas = document.getElementById('starfield-canvas');
        
        // Create starfield with default settings (recommended)
        const starfield = new RealisticStarfield(canvas);

        // OR with custom options:
        // const starfield = new RealisticStarfield(canvas, {
        //     starCount: 1000,              // More stars
        //     backgroundColor: '#0a0a0a',   // Slightly lighter black
        //     meteorInterval: 6000,         // Meteor every 6 seconds
        //     meteorAngle: 40,              // Steeper angle
        //     enableMeteors: true,          // Enable shooting stars
        //     enableTwinkle: true,          // Enable twinkling
        //     twinkleIntensity: 0.4         // Twinkle amount (0-1)
        // });

        // Trigger a meteor manually (e.g., on button click)
        // starfield.triggerMeteor();

        // Update options dynamically
        // starfield.setOptions({ meteorInterval: 3000 });
    </script>
</body>
</html>

Option B: ES6 Module Import

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Same styles as above -->
</head>
<body>
    <canvas id="starfield-canvas"></canvas>
    <div class="content">
        <h1>Welcome</h1>
    </div>

    <script type="module">
        import RealisticStarfield from './src/index.js';
        // OR for backward compatibility:
        // import { ConstellationBackground } from './src/index.js';
        
        const canvas = document.getElementById('starfield-canvas');
        const starfield = new RealisticStarfield(canvas);
    </script>
</body>
</html>

Method 2: React

Basic Implementation

import React, { useEffect, useRef } from 'react';
import RealisticStarfield from 'my-constellation-bg';

function App() {
  const canvasRef = useRef(null);
  const starfieldRef = useRef(null);

  useEffect(() => {
    if (canvasRef.current) {
      starfieldRef.current = new RealisticStarfield(canvasRef.current, {
        starCount: 800,
        meteorInterval: 8000
      });
    }

    return () => {
      if (starfieldRef.current) {
        starfieldRef.current.destroy();
      }
    };
  }, []);

  return (
    <div style={{ position: 'relative', width: '100vw', height: '100vh' }}>
      <canvas
        ref={canvasRef}
        style={{
          position: 'fixed',
          top: 0,
          left: 0,
          width: '100%',
          height: '100%',
          zIndex: -1
        }}
      />
      
      <div style={{
        position: 'relative',
        zIndex: 1,
        color: 'white',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        height: '100vh',
        flexDirection: 'column'
      }}>
        <h1>Welcome to My App</h1>
        <p>Built with React ⚛️</p>
      </div>
    </div>
  );
}

export default App;

Reusable Component

// StarfieldCanvas.jsx
import React, { useEffect, useRef } from 'react';
import RealisticStarfield from 'my-constellation-bg';

const StarfieldCanvas = ({ options = {} }) => {
  const canvasRef = useRef(null);
  const starfieldRef = useRef(null);

  useEffect(() => {
    if (canvasRef.current && !starfieldRef.current) {
      starfieldRef.current = new RealisticStarfield(
        canvasRef.current,
        options
      );
    }

    return () => {
      if (starfieldRef.current) {
        starfieldRef.current.destroy();
        starfieldRef.current = null;
      }
    };
  }, [options]);

  return (
    <canvas
      ref={canvasRef}
      style={{
        position: 'fixed',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        zIndex: -1
      }}
    />
  );
};

export default StarfieldCanvas;

Usage:

import StarfieldCanvas from './StarfieldCanvas';

function App() {
  return (
    <>
      <StarfieldCanvas 
        options={{
          starCount: 1000,
          meteorInterval: 5000
        }}
      />
      <div className="content">
        <h1>Your Content Here</h1>
      </div>
    </>
  );
}

Method 3: Vue 3

Composition API

<template>
  <div class="container">
    <canvas ref="canvasRef" class="starfield-canvas"></canvas>
    <div class="content">
      <h1>Welcome to Vue App</h1>
      <p>Powered by Vue 3 🟢</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import RealisticStarfield from 'my-constellation-bg';

const canvasRef = ref(null);
let starfield = null;

onMounted(() => {
  if (canvasRef.value) {
    starfield = new RealisticStarfield(canvasRef.value, {
      starCount: 800,
      meteorInterval: 8000
    });
  }
});

onBeforeUnmount(() => {
  if (starfield) {
    starfield.destroy();
  }
});
</script>

<style scoped>
.container {
  position: relative;
  width: 100vw;
  height: 100vh;
}

.starfield-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}

.content {
  position: relative;
  z-index: 1;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  flex-direction: column;
}

h1 {
  font-size: 3rem;
  margin-bottom: 1rem;
}
</style>

Options API

<template>
  <div class="container">
    <canvas ref="canvas" class="starfield-canvas"></canvas>
    <div class="content">
      <h1>Your Content</h1>
    </div>
  </div>
</template>

<script>
import RealisticStarfield from 'my-constellation-bg';

export default {
  data() {
    return {
      starfield: null
    };
  },
  mounted() {
    this.starfield = new RealisticStarfield(this.$refs.canvas, {
      starCount: 800,
      meteorInterval: 8000
    });
  },
  beforeUnmount() {
    if (this.starfield) {
      this.starfield.destroy();
    }
  }
};
</script>

<style scoped>
.container {
  position: relative;
  width: 100vw;
  height: 100vh;
}

.starfield-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}

.content {
  position: relative;
  z-index: 1;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  flex-direction: column;
}
</style>

⚙️ Configuration Options

Customize the appearance and behavior:

const starfield = new RealisticStarfield(canvas, {
  starCount: 800,                 // Number of stars (scales with screen size)
  backgroundColor: '#000000',     // Pure black deep space
  meteorInterval: 8000,           // Time between meteors (ms)
  meteorAngle: 35,                // Meteor angle in degrees
  enableMeteors: true,            // Enable/disable shooting stars
  enableTwinkle: true,            // Enable/disable star twinkling
  twinkleIntensity: 0.3           // Twinkle strength (0-1)
});

Options Reference

| Option | Type | Default | Description | |--------|------|---------|-------------| | starCount | Number | 800 | Base number of stars (auto-scales with screen size) | | backgroundColor | String | '#000000' | Canvas background color (pure black recommended) | | meteorInterval | Number | 8000 | Time between meteor spawns (milliseconds) | | meteorAngle | Number | 35 | Fixed angle for meteors in degrees (from vertical) | | enableMeteors | Boolean | true | Enable or disable shooting stars | | enableTwinkle | Boolean | true | Enable or disable star twinkling effect | | twinkleIntensity | Number | 0.3 | How much stars twinkle (0 = none, 1 = maximum) |

Meteor Speed Distribution

Meteors spawn with varying speeds for a realistic effect:

  • 40% Slow Meteors - Graceful, long trails (speed: 2-3.5)
  • 40% Medium Meteors - Balanced appearance (speed: 4-6)
  • 20% Fast Meteors - Quick bright streaks (speed: 8-12)

Star Brightness Distribution

Stars are distributed with realistic brightness levels:

  • 70% Dim Stars - Tiny, faint (like distant stars)
  • 20% Medium Stars - Moderate brightness
  • 7% Bright Stars - Clearly visible
  • 3% Very Bright Stars - With glow effect

🎨 Styling Examples

Default Realistic Night Sky

// Just use defaults - they look like a real photo!
new RealisticStarfield(canvas);

Dense Starfield

new RealisticStarfield(canvas, {
  starCount: 1500,        // More stars
  meteorInterval: 5000    // More frequent meteors
});

Subtle Background (Less Distracting)

new RealisticStarfield(canvas, {
  starCount: 400,         // Fewer stars
  meteorInterval: 15000,  // Rare meteors
  twinkleIntensity: 0.2   // Very subtle twinkle
});

No Meteors (Static Starfield)

new RealisticStarfield(canvas, {
  enableMeteors: false,   // Disable shooting stars
  enableTwinkle: true     // Keep twinkling
});

🎯 Common Use Cases

Hero Section Background

<style>
    .hero {
        position: relative;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    
    #hero-canvas {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: -1;
    }
</style>

<section class="hero">
    <canvas id="hero-canvas"></canvas>
    <div class="hero-content">
        <h1>Your Hero Title</h1>
        <p>Subtitle goes here</p>
    </div>
</section>

<script src="dist/index.js"></script>
<script>
    const canvas = document.getElementById('hero-canvas');
    new RealisticStarfield(canvas);
</script>

Full Page Background (with scrollable content)

<style>
    body {
        margin: 0;
        background: #000;
    }
    
    #bg-canvas {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: -1;
    }
    
    main {
        position: relative;
        z-index: 1;
        min-height: 100vh;
        color: white;
        padding: 2rem;
    }
</style>

<canvas id="bg-canvas"></canvas>
<main>
    <h1>Page Title</h1>
    <p>Your content scrolls normally while background stays fixed</p>
    <!-- More content... -->
</main>

<script src="dist/index.js"></script>
<script>
    const canvas = document.getElementById('bg-canvas');
    new RealisticStarfield(canvas);
</script>

🛠️ API Reference

Constructor

new RealisticStarfield(canvas, options)
// OR for backward compatibility:
new ConstellationBackground(canvas, options)

Creates a new starfield instance.

Parameters:

  • canvas (HTMLCanvasElement) - The canvas element to render on
  • options (Object, optional) - Configuration object

Returns: RealisticStarfield instance

Methods

destroy()

Stops the animation and cleans up event listeners. Always call this when removing the canvas (especially in SPAs).

starfield.destroy();

setOptions(options)

Update options dynamically without recreating the instance.

starfield.setOptions({ meteorInterval: 5000 });

triggerMeteor()

Manually trigger a shooting star (e.g., on button click or event).

starfield.triggerMeteor();

resize()

Manually trigger a resize. Usually called automatically on window resize.

starfield.resize();

📁 File Structure

my-constellation-bg/
├── dist/
│   └── index.js          # Built file (after npm run build)
├── src/
│   └── index.js          # Source file (RealisticStarfield class)
├── test.js               # Test suite
├── index.html            # Demo page
├── package.json
└── README.md

💡 Best Practices

  1. Z-index: Always set canvas z-index: -1 to keep it behind content
  2. Fixed positioning: Use position: fixed for full-page backgrounds
  3. Performance: Lower starCount for better mobile performance (try 100-150)
  4. Cleanup: Always call destroy() when unmounting (React/Vue components)
  5. Responsive: Canvas automatically resizes, no additional code needed
  6. Build first: Run npm run build before using in production

🌐 Browser Support

Works in all modern browsers that support:

  • Canvas API
  • ES6 Classes
  • RequestAnimationFrame

Tested on: Chrome, Firefox, Safari, Edge


🎯 Real-World Examples

  • Landing page hero sections
  • Login/signup page backgrounds
  • Portfolio websites
  • Dashboard backgrounds
  • Loading screens
  • Presentation slides
  • Marketing pages

� Changelog

v1.2.0 (2026-01-02)

Major Update - Grok-style Improvements

  • Fixed Position Stars: Stars now have anchor positions with subtle drift movement
  • ☄️ Variable Speed Meteors: Added slow (30%), medium (50%), and fast (20%) meteor types
  • 💫 Bright Star Glow: 15% of stars now feature a special radial glow effect
  • 🎨 Enhanced Meteor Colors: Different meteor speeds have unique color schemes
  • ⚙️ New Options: Added starDrift and driftSpeed configuration options
  • 🐛 Performance: Optimized animation loop for smoother rendering

v1.1.3

  • Bug fixes and stability improvements

v1.1.0

  • Initial public release with blinking stars, connections, and meteors

�📄 License

MIT © Anupam Raj

🤝 Contributing

Contributions, issues, and feature requests are welcome!

Feel free to check (https://github.com/anupamraj176/my-constellation-bg).

💖 Support

If you like this project, please give it a ⭐ on GitHub!


Made with ☄️ by Anupam Raj