🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@eldrex/my-free-package

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Package was removed
Sorry, it seems this package was removed from the registry

@eldrex/my-free-package

Ultra-lightweight static site compiler library with built-in automatic reactivity, SPA router, custom ciphers, and IndexedDB CRUD engine.

latest
npmnpm
Version
3.0.0
Version published
Maintainers
1
Created
Source
Papyr.js banner

📄 Papyrus (papyr.js) — HTML Made Stupid Simple

Write HTML like you're writing a text message.

MIT License Zero Dependencies Bundle Size

Papyrus is an ultra-lightweight, blazing-fast JavaScript library designed to build modern interactive HTML interfaces with absolute zero complexity and zero terminal setups. By bypassing the Virtual DOM, Papyrus delivers direct DOM manipulation with reactive state tracking, enterprise-grade security, and a delightfully simple API.

Papyrus v2.0 introduces a state-of-the-art Agile Modular Architecture, featuring automatic dependency-tracking reactivity, built-in enterprise vault encryption, HTML5 SPA routing, reactive mathematical computations, and advanced physics-based animations—all without a single npm dependency.

[!IMPORTANT] Read the Official Master Manual (DOCS.md) for a complete, in-depth guide covering fundamentals, reactive data types, database CRUD engines, security ciphers, styling utilities, and a side-by-side comparison cheat sheet mapping Vanilla JS patterns directly to boilerplate-free Papyr.js.

📚 Table of Contents

⚡ Core Philosophy

  • One Function. One Rule. Zero Complexity: If you know standard HTML tags and JavaScript objects, you already know Papyrus.
  • XSS-Immune Secure Engine: Transparently sanitizes strings, removing dangerous script vectors and pseudo-protocols dynamically.
  • No NPM or Terminal Overhead Required: include a single CDN link inside a bare HTML file and hit refresh.
  • CSS Spotlight Design System: Loaded with premium dark grids, radial glows, glassmorphism panel states, and fluid scroll animations out of the box.
  • Enterprise-Ready Reactivity: Fine-grained dependency tracking with zero virtual DOM overhead—direct DOM updates.

✨ Features

Core Features

  • Ultra-fast DOM creation — Direct element generation without Virtual DOM
  • 🔋 Automatic reactivity — State tracking with computed properties and subscribers
  • 🔐 Enterprise security — Built-in XSS sanitization and encrypted storage vault
  • 🎨 Premium UI components — Pre-built modals, cards, forms, tables, and animations
  • 📱 Mobile-first responsive — Automatic breakpoint handling and mobile optimizations
  • 🧮 Reactive math engine — Build dynamic financial models and dashboards
  • 💾 Multi-engine persistence — LocalStorage, SessionStorage, Firebase, SQLite support
  • 🎬 Physics & animation engine — Particle systems, spring physics, gesture controls
  • 🎙️ Speech & vision API — Built-in speech recognition and image processing
  • 🤖 AI/ML toolkit — Classifiers, QR scanning, computer vision integration
  • 🌐 HTML5 SPA routing — Client-side routing with dynamic parameters
  • 🔌 Plugin system — Extend with custom plugins and hooks
  • 0️⃣ Zero dependencies — Single 12KB gzipped library with no external libraries

🚀 Installation

CDN (Fastest Setup)

<script src="https://papyrus-js.vercel.app/papyr-complete.js"></script>

Modular CDN (Load Only What You Need)

<!-- Core only (~13.8KB gzipped) -->
<script src="https://papyrus-js.vercel.app/papyr-core.js"></script>

<!-- + UI Components (~29.6KB gzipped) -->
<script src="https://papyrus-js.vercel.app/papyr-ui.js"></script>

<!-- + Advanced (Physics, 3D, ML) (~23.1KB gzipped) -->
<script src="https://papyrus-js.vercel.app/papyr-advanced.js"></script>

📦 Bundle Size Breakdown (v3.0)

ModuleMinifiedGzippedFeatures
papyr.js (Core)140.96 KB25.33 KBReactivity, DOM, Router, storage
papyr.min.js (Core Min)51.63 KB13.78 KBReactivity, DOM, Router, storage
papyr-ui.min.js (UI Min)111.15 KB29.62 KBComponents, Layout, Design, styling
papyr-advanced.min.js (Adv Min)78.62 KB23.09 KBPhysics, Charts, ML
papyr-complete.min.js (Comp Min)157.07 KB44.55 KBAll features compiled

Lazy-Loaded Dependencies

Advanced features like 3D scenes lazy-load heavy external code (like Three.js) dynamically from CDNs only when used, keeping the baseline package sizes minimal.

⏱️ Quick Start (60 seconds)

1️⃣ Create an HTML File

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Papyrus App</title>
    <script src="https://papyrus-js.vercel.app/papyr-complete.js"></script>
</head>
<body>
    <div id="app"></div>

    <script>
        // Define a reactive counter
        let count = papyr.state(0);

        // Create a component tree
        let App = papyr.div(
            papyr.h1("Hello Papyr! 🚀"),
            papyr.button(
                () => `Clicked ${count.value} times`,
                { onclick: () => count.value++ }
            )
        );

        // Mount to DOM
        papyr.mount('#app', App);
    </script>
</body>
</html>

That's it! Open in your browser and watch it work.

🎯 Core Concepts

1. Reactive State

// Create a reactive state
let count = papyr.state(0);

// Read value
console.log(count.value); // 0

// Update (automatically re-renders UI)
count.value++;

// Subscribe to changes
count.subscribe(newValue => {
    console.log("Count changed to:", newValue);
});

2. Computed Properties

let price = papyr.state(100);
let taxRate = papyr.state(0.08);

// Automatically recomputes when dependencies change
let totalPrice = papyr.computed(() => {
    return price.value * (1 + taxRate.value);
});

console.log(totalPrice.value); // 108
price.value = 200;
console.log(totalPrice.value); // 216 (auto-updated!)

3. Conditional Rendering

let isLoggedIn = papyr.state(false);

let UI = papyr.div(
    papyr.if(
        isLoggedIn,
        papyr.p("Welcome back!"),
        papyr.p("Please log in.")
    )
);

4. List Rendering

let todos = papyr.state([
    { id: 1, text: "Learn Papyr" },
    { id: 2, text: "Build app" }
]);

let TodoList = papyr.div(
    papyr.for(todos, (todo) => 
        papyr.div(
            papyr.p(todo.text),
            papyr.button("Done", { onclick: () => {
                todos.value = todos.value.filter(t => t.id !== todo.id);
            }})
        )
    )
);

5. Reactive Math

let salary = papyr.state(50000);
let bonus = papyr.state(5000);
let tax = papyr.state(0.2);

let netIncome = papyr.computed(() => {
    let gross = papyr.math.sum(salary, bonus).value;
    let taxAmount = papyr.math.mul(gross, tax).value;
    return papyr.math.sub(gross, taxAmount).value;
});

📖 API Reference

DOM Creation

FunctionUsageReturns
papyr.div(...)Create <div> elementHTMLElement
papyr.h1-h6(...)Create headingsHTMLElement
papyr.p(text, options)Create <p>HTMLElement
papyr.button(text, options)Create <button>HTMLElement
papyr.input(type, placeholder, options)Create <input>HTMLElement
papyr.form(...children)Create form wrapperHTMLElement
papyr.span(...)Create <span>HTMLElement
papyr.a(text, href, options)Create <a> linkHTMLElement
papyr.img(src, alt, options)Create <img>HTMLElement

State Management

FunctionUsageReturns
papyr.state(initialValue)Create reactive stateStateObject
papyr.computed(fn)Create computed propertyComputedObject
papyr.if(condition, trueNode, falseNode)Conditional renderingHTMLElement
papyr.for(array, renderFn)List renderingHTMLElement

Layout Helpers

FunctionUsage
papyr.flex.row(...children)Flex-row layout
papyr.flex.col(...children)Flex-column layout
papyr.flex.center(...children)Centered flex layout
papyr.flex.between(...children)Space-between layout
papyr.grid(...children)CSS grid layout
papyr.container(...children)Max-width container

Components

FunctionPurpose
papyr.card(title, content, footer)Card widget
papyr.modal(content, title)Modal dialog
papyr.toast(message, type, duration)Toast notification
papyr.tabs(tabArray)Tabbed interface
papyr.carousel(images)Image carousel
papyr.table(...args)Data table

Storage & Security

FunctionPurpose
papyr.storage.set(key, value)Store JSON in LocalStorage
papyr.storage.get(key)Retrieve from LocalStorage
papyr.storage.secureSet(key, value, password)Encrypted storage
papyr.storage.secureGet(key, password)Retrieve encrypted data
papyr.security.sanitize(html)Remove XSS vectors

Database

FunctionPurpose
papyr.crud(collectionName, initialData)Create persistent CRUD DB
papyr.db(collectionName, engine)Access multi-engine DB

Engines: 'local', 'session', 'firebase', 'sqlite'

Math Engine

FunctionPurpose
papyr.math.sum(...args)Reactive sum
papyr.math.sub(a, b)Reactive subtraction
papyr.math.mul(...args)Reactive multiplication
papyr.math.div(a, b)Reactive division
papyr.math.avg(...args)Reactive average
papyr.math.percent(val, total)Percentage calculation
papyr.math.round(val, decimals)Precision rounding

Routing

FunctionPurpose
papyr.route(path, componentFn)Define route
papyr.navigate(path)Navigate to route
papyr.useParams()Get route parameters

Animations

FunctionPurpose
papyr.animate(el, properties, duration)Animate element
papyr.animate.fade(el, duration)Fade in/out
papyr.animate.slide(el, duration)Slide animation
papyr.animate.zoom(el, duration)Zoom animation
papyr.animate.spring(el, properties, config)Spring physics
papyr.parallax(selector, speed)Parallax effect

Media & Advanced

FunctionPurpose
papyr.particles(options)Particle system
papyr.physics(options)Physics engine
papyr.chart(type, data, options)Chart rendering
papyr.ai.scan(image)QR/barcode scanning
papyr.ai.speak(text, options)Text-to-speech
papyr.ai.listen(options)Speech recognition
papyr.clipboard.copy(text)Copy to clipboard
papyr.file.open()File picker
papyr.camera.request()Camera access

Utilities

FunctionPurpose
papyr.mount(selector, component)Mount component to DOM
papyr.fragment(...children)Fragment wrapper (no DOM node)
papyr.html(htmlString)Parse HTML string
papyr.delay(ms)Sleep/delay promise
papyr.copy(text)Copy text to clipboard
papyr.debug(true/false)Enable debug mode
papyr.noConflict()Release global namespace

🔒 Security Best Practices

⚠️ Important Security Notes

Papyrus includes built-in XSS protection, but you should follow these practices:

  • Use papyr.security.sanitize() for user input:
let userInput = "<img src=x onerror='alert(1)'>";
let safeHTML = papyr.security.sanitize(userInput);
// Dangerous scripts are automatically removed
  • Be aware of encryption limitations:

[!WARNING]

Storage "Secure" Sync Methods Are Obfuscation, NOT Encryption

The synchronous secureSet() and secureGet() methods use XOR + Base64 obfuscation, which provides ZERO cryptographic security against malicious memory inspection or storage extraction. This is suitable only for basic obfuscation.

Real Encryption: Use Async Methods (AES-256-GCM)

For actual cryptographic security (e.g. session tokens or sensitive data), you MUST use the asynchronous methods which leverage browser-native Web Crypto API AES-GCM 256-bit with PBKDF2:

// ✅ Encrypted using AES-256-GCM
await papyr.storage.secureSetAsync("token", userToken, myPassword);
let userToken = await papyr.storage.secureGetAsync("token", myPassword);
  • Set Content Security Policy headers:
Content-Security-Policy: 
  default-src 'self'; 
  script-src 'self' https://papyrus-js.vercel.app;
  style-src 'self' 'unsafe-inline';
  • Secure storage recommendations:
// ✅ DO: Use secure storage for sensitive data
papyr.storage.secureSet("user-session", token, secretKey);

// ❌ DON'T: Store secrets in plain localStorage
papyr.storage.set("secret", secretValue);

// ⚠️ CAUTION: Browser storage is vulnerable to XSS attacks
// Use server-side sessions for highly sensitive data
  • Sanitize all dynamic content:
// ✅ Safe: Content is auto-escaped
papyr.p("User: " + userInput);

// ⚠️ Risky: Bypasses security if userInput contains HTML
papyr.html(userInput);

// ✅ Safe: Use sanitizer first
papyr.html(papyr.security.sanitize(userInput));

Security Tier Levels

// Set security tier for your app
papyr.security.setTier('basic');     // XSS protection only
papyr.security.setTier('standard');  // + Input validation
papyr.security.setTier('enterprise'); // + Encryption, CSP enforcement

🚀 Advanced Examples

1. Building a Todo App

let todos = papyr.crud("todos", []);

let TodoApp = papyr.div(
    papyr.h1("📝 My Todos"),
    
    // Input form
    papyr.form(
        papyr.input("text", "Add a todo...", {
            id: "todo-input",
            onkeypress: (e) => {
                if (e.key === "Enter") {
                    let input = document.getElementById("todo-input");
                    if (input.value) {
                        todos.insert({ text: input.value, done: false });
                        input.value = "";
                    }
                }
            }
        })
    ),
    
    // Todo list
    papyr.for(todos.state, (todo) =>
        papyr.div(
            papyr.flex.between(
                papyr.p(todo.text),
                papyr.button("Done", {
                    onclick: () => todos.delete(todo.id)
                })
            )
        )
    )
);

papyr.mount("#app", TodoApp);

2. Interactive Dashboard with Math

let revenue = papyr.state(50000);
let expenses = papyr.state(30000);
let growth = papyr.state(0.12);

let profit = papyr.math.sub(revenue, expenses);
let projectedRevenue = papyr.computed(() => 
    papyr.math.mul(revenue, papyr.math.sum(1, growth)).value
);

let Dashboard = papyr.div(
    papyr.h1("💰 Business Dashboard"),
    papyr.flex.row(
        papyr.card("Revenue", () => "$" + revenue.value),
        papyr.card("Expenses", () => "$" + expenses.value),
        papyr.card("Profit", () => "$" + profit.value)
    ),
    papyr.card("Projected Revenue", () => "$" + projectedRevenue.value)
);

papyr.mount("#app", Dashboard);

3. SPA with Routing

// Define routes
papyr.route("/", () => papyr.div(papyr.h1("Home")));
papyr.route("/about", () => papyr.div(papyr.h1("About")));
papyr.route("/user/:id", () => {
    let params = papyr.useParams();
    return papyr.div(papyr.h1(`User ${params.id}`));
});

// Create navigation
let Nav = papyr.div(
    papyr.a("Home", "/"),
    papyr.a("About", "/about")
);

papyr.mount("#app", papyr.div(Nav, papyr.router()));

4. Animation & Physics

let box = papyr.div("🎁", {
    style: { width: "50px", height: "50px", background: "teal" }
});

// Spring physics animation
papyr.animate.spring(box, {
    translateX: 200,
    rotate: 360
}, {
    tension: 0.4,
    friction: 0.1
});

// Particle system
let particles = papyr.particles({
    count: 100,
    life: 2,
    velocity: { x: [-5, 5], y: [-5, 5] }
});

papyr.mount("#app", papyr.div(box, particles));

📱 Mobile Responsiveness

Papyrus automatically handles responsive design:

let ResponsiveLayout = papyr.div(
    papyr.flex.col(  // Stacks vertically on mobile
        papyr.div({ class: "sidebar" }, "Menu"),
        papyr.div({ class: "content" }, "Main Content")
    )
);

// Automatic breakpoints (under 768px = mobile layout)
// Use CSS classes for fine-tuning:
// .mobile-header, .menu-toggle, .responsive-split-grid

⚙️ Performance Optimization

Tips for Maximum Performance

  • Use papyr.computed() wisely:
// ✅ Efficient: Only recomputes when dependencies change
let expensive = papyr.computed(() => complexCalculation(value));

// ❌ Inefficient: Recalculates on every DOM update
papyr.p(() => complexCalculation(value.value));
  • Batch state updates:
// ❌ Slow: 100 DOM updates
for (let i = 0; i < 100; i++) items.value.push(i);

// ✅ Fast: Single DOM update
items.value = [...items.value, ...Array.from({length: 100}, (_, i) => i)];
  • Use fragments for large lists:
let BigList = papyr.fragment(
    ...largeArray.map(item => papyr.p(item))
);
  • Lazy-load advanced features:
// Only load physics if you need it
if (needsPhysics) {
    let physics = papyr.physics({ gravity: 10 });
}

Performance Benchmarks

OperationTime
State creation< 0.1ms
DOM element creation< 0.5ms
State update + re-render< 2ms
1000-item list render~50ms
Computed value update< 0.1ms

🌐 Browser Support

BrowserSupportMin Version
Chrome✅ Full60+
Firefox✅ Full55+
Safari✅ Full11+
Edge✅ Full79+
IE11⚠️ LimitedPolyfills needed
Mobile Chrome✅ Full60+
Mobile Safari✅ Full11+

🔥 Reactive Mathematical Studio (papyr.math)

Build complex reactive equation trees instantly:

let price = papyr.state(100);
let discount = papyr.state(15);
let tax = papyr.state(8);

let discountAmount = papyr.math.mul(price, papyr.math.div(discount, 100));
let discountedPrice = papyr.math.sub(price, discountAmount);
let taxAmount = papyr.math.mul(discountedPrice, papyr.math.div(tax, 100));
let finalTotal = papyr.math.round(papyr.math.sum(discountedPrice, taxAmount), 2);

let CheckoutUI = papyr.div(
    papyr.h3("🛒 Checkout Summary"),
    papyr.p(() => "Price: $" + price.value),
    papyr.p(() => "After Discount: $" + discountedPrice.value.toFixed(2)),
    papyr.p(() => "Tax: $" + taxAmount.value.toFixed(2)),
    papyr.h2(() => "Total: $" + finalTotal.value.toFixed(2))
);

💾 Multi-Engine Database

// Choose your storage engine
let tasks = papyr.crud("tasks", [], "local");      // LocalStorage (default)
let sessions = papyr.crud("sessions", [], "session"); // SessionStorage
let backup = papyr.crud("backup", [], "firebase");    // Firebase Realtime DB
let offline = papyr.crud("offline", [], "sqlite");    // SQLite (offline-first)

// Same API for all engines
tasks.insert({ id: 1, title: "Learn Papyr" });
tasks.update(1, { title: "Master Papyr" });
tasks.delete(1);

🎨 Premium UI Components

Cards

let card = papyr.card("Title", "Content", "Footer");

Modals

let modal = papyr.modal(
    papyr.p("Are you sure?"),
    "Confirm Action"
);
modal.show();
modal.hide();

Tabs

let tabs = papyr.tabs([
    { label: "Tab 1", content: papyr.p("Content 1") },
    { label: "Tab 2", content: papyr.p("Content 2") }
]);

Forms

let form = papyr.form(
    papyr.input("text", "Name", { name: "name" }),
    papyr.input("email", "Email", { name: "email" }),
    papyr.button("Submit", { onclick: () => {} })
);

🤝 Contributing

We welcome contributions! Here's how you can help:

Areas Needing Help

  • 📚 Documentation improvements
  • 🐛 Bug reports and fixes
  • ✨ New UI component designs
  • 🚀 Performance optimizations
  • 🔐 Security enhancements
  • 🌍 Internationalization (i18n)
  • ♿ Accessibility (a11y) improvements

Development Setup

# Clone the repository
git clone https://github.com/EldrexDelosReyesBula/Papyr.js.git
cd Papyr.js

# Build distribution
node build.js

Code Style

  • Use functional programming where possible
  • Keep functions small and focused
  • Add JSDoc comments for public APIs
  • Follow existing naming conventions

Reporting Issues

  • Use GitHub Issues for bugs
  • Provide a minimal reproducible example
  • Include browser and OS information
  • Share error logs and stack traces

📄 File Structure

Papyr.js/
├── src/
│   ├── core/                  # Core modules (reactivity, router, security, db, orm, etc.)
│   ├── plugins/               # Official plugins (ui elements, math, physics, charts, etc.)
│   └── styles/                # CSS design system complete tokens
├── build.js                   # Library compiler/bundler script
├── package.json               # NPM metadata
├── README.md                  # This markdown documentation
├── CONTRIBUTING.md            # Contribution guide
└── LICENSE                    # MIT License

🛡️ Spellcheck Debugger Warnings

Papyrus protects beginners from typos:

// Typo detected!
let myBtn = papyr.buton("Click me"); 
// Console: "PapyrWarning: Unknown tag 'buton'. Did you mean 'button'?"

// Enable debug mode to see all warnings
papyr.debug(true);

🔌 Namespace Harmony

Working with legacy code?

// Release global namespace
const myPapyr = papyr.noConflict();

// Original window.papyr is restored
myPapyr.mount("#app", myPapyr.div("Safe!"));

📊 Comparison with Other Frameworks

FeaturePapyrusReactVueSvelte
Bundle Size12KB42KB34KB16KB
Learning CurveVery EasyMediumMediumEasy
No Build Tools
Direct DOM
Reactivity
Built-in Components
Zero Dependencies
Encryption Built-in

🎓 Learning Resources

📞 Support & Community

📄 License

Papyrus is released under the MIT License. See LICENSE for details.

MIT License

Copyright (c) 2026 Eldrex Delos Reyes Bula

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction...

🙏 Acknowledgments

  • Inspired by Vue.js's reactivity model
  • Physics engine concepts from Three.js and Babylon.js
  • Security practices from OWASP guidelines
  • Community feedback and contributions

IMPORTANT NOTICE FOR DEVELOPERS AND ENTERPRISES:

  • Beta Classification & Active Development: Papyrus.js (papyr.js) is currently in a highly active development phase (Beta status). While it is continuously optimized and tested, it may not perform as robustly or function as perfectly as modern massive web frameworks (such as React, Vue, or Next.js) that have extensive multi-year optimizations.
  • "AS-IS" Distribution: The library, including all modular and complete CDN bundles, is provided completely "AS-IS" without any warranty of any kind, express or implied.
  • Absence of Liability: IN NO EVENT shall the author(s), publisher, or contributors be held liable for any claim, damages, security breaches, data loss, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use of the library.
  • Developer Implementation Responsibility: The developer assuming integration of Papyrus.js is solely responsible for verifying the security, XSS sanitization levels, WATT storage tracking consent flows, and legal compliance of their own final applications. No liability is assumed for developer implementation errors, security misconfigurations, or operational failures of their final built apps.
  • Continuous Improvements: By utilizing this library, you acknowledge its experimental/lightweight nature and agree to hold the authors completely harmless under the terms of the MIT License.

📄 License

Papyrus is released under the MIT License. See LICENSE for details.

MIT License

Copyright (c) 2026 Eldrex Delos Reyes Bula

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Papyrus v3.0.0 — Built with zero dependencies. Crafted with passion for simplicity.

Start building beautiful apps today: https://papyrus-js.vercel.app/

Keywords

reactive

FAQs

Package last updated on 02 Jun 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts