
Research
2025 Report: Destructive Malware in Open Source Packages
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.
@wroud/navigation
Advanced tools
A flexible, pattern-matching navigation system for JavaScript applications with built-in routing, browser integration, and navigation state management
@wroud/navigation is a flexible, pattern-matching navigation system for JavaScript applications. It provides a framework-agnostic routing solution with powerful pattern matching capabilities, browser integration, and navigation state management.
/users/:id), and wildcard patterns (/files/:path*).Install via npm:
npm install @wroud/navigation
Install via yarn:
yarn add @wroud/navigation
For detailed usage and API reference, visit the documentation site.
import { Navigation, Router } from "@wroud/navigation";
// Create a router with default settings
const router = new Router();
// Add routes
router.addRoute({ id: "/" });
router.addRoute({ id: "/users" });
router.addRoute({ id: "/users/:id" });
// Create a navigation instance with the router
const navigation = new Navigation(router);
// Navigate to a route
await navigation.navigate({ id: "/users/:id", params: { id: "123" } });
// Get current route state
const currentState = navigation.getState();
console.log(currentState); // { id: "/users/:id", params: { id: "123" } }
// Go back to previous route
await navigation.goBack();
import { Navigation, Router, TriePatternMatching } from "@wroud/navigation";
// Create a router with pattern matching
const router = new Router({
matcher: new TriePatternMatching({ trailingSlash: false })
});
// Add routes
router.addRoute({ id: "/" });
router.addRoute({ id: "/app" });
router.addRoute({ id: "/app/users" });
router.addRoute({ id: "/app/users/:id" });
// Create a navigation instance
const navigation = new Navigation(router);
// Match a URL to a route
const match = router.matchUrl("/app/users/123");
console.log(match); // { id: "/app/users/:id", params: { id: "123" } }
// Build a URL from a route and parameters
const url = router.buildUrl("/app/users/:id", { id: "456" });
console.log(url); // "/app/users/456"
// Navigate using the pattern matching
await navigation.navigate(router.matchUrl("/app/users/789"));
import { Navigation, Router, TriePatternMatching } from "@wroud/navigation";
import { BrowserNavigation } from "@wroud/navigation/browser";
// Create a router with pattern matching
const router = new Router({
matcher: new TriePatternMatching({
trailingSlash: true,
base: '/app' // Base path for the application
})
});
// Add routes
router.addRoute({ id: "/" });
router.addRoute({ id: "/products" });
router.addRoute({ id: "/products/:id" });
router.addRoute({ id: "/blog/:year/:month/:slug" });
// Create a navigation instance
const navigation = new Navigation(router);
// Add a navigation listener for all navigation events
// including the initial navigation
const unsubscribe = navigation.addListener((type, from, to) => {
if (type === "navigate" && !from) {
console.log("Initial navigation:", to);
} else {
console.log(`Navigation: ${type}`, { from, to });
}
});
// Create a browser navigation instance
const browserNavigation = new BrowserNavigation(navigation);
// Initialize browser navigation by registering routes
// This will sync with the browser's URL and history
await browserNavigation.registerRoutes();
// Navigate - this will update the browser URL
await navigation.navigate({
id: "/products/:id",
params: { id: "123" }
});
// Browser URL is now /app/products/123
// Later, remove the listener
unsubscribe();
import { Navigation, Router } from "@wroud/navigation";
// Create a router
const router = new Router();
// Add routes with navigation guards
router.addRoute({
id: "/",
});
router.addRoute({
id: "/dashboard",
// Check if user is authenticated before activating this route
canActivate: (to, from) => {
return isAuthenticated(); // Your authentication check
}
});
router.addRoute({
id: "/editor/:documentId",
// Check if user has permission to edit this document
canActivate: async (to, from) => {
if (!to.params.documentId) return false;
return await hasEditPermission(to.params.documentId);
},
// Ask for confirmation before navigating away
canDeactivate: (to, from) => {
return confirm("Discard unsaved changes?");
}
});
const navigation = new Navigation(router);
// This will fail if not authenticated
await navigation.navigate({ id: "/dashboard", params: {} });
All notable changes to this project will be documented in the CHANGELOG file.
This project is licensed under the MIT License. See the LICENSE file for details.
FAQs
Did you know?

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.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.

Research
/Security News
A five-month operation turned 27 npm packages into durable hosting for browser-run lures that mimic document-sharing portals and Microsoft sign-in, targeting 25 organizations across manufacturing, industrial automation, plastics, and healthcare for credential theft.