
Security News
rv Is a New Rust-Powered Ruby Version Manager Inspired by Python's uv
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
[](https://www.npmjs.com/package/scn-js) [](https://github.com/scn-lang/scn) [ from JavaScript and TypeScript codebases.
It's a command-line tool and programmatic library that analyzes your project's structure—classes, functions, types, interfaces, and their relationships across files—and outputs a hyper-efficient SCN map. This map is designed to be fed directly into Large Language Models (LLMs), giving them unparalleled architectural context at a fraction of the token cost of raw source code.
This tool is your bridge over the "Context Chasm," enabling smarter, faster, and more accurate AI-assisted development.
scn.config.js
)Symbolic Context Notation (SCN) is a format designed to represent a software project's structural surface, API, and inter-file relationships. It strips away implementation logic to create a compressed blueprint of your codebase.
Before SCN (Raw Code) | After SCN (Context Map) | Token Savings |
---|---|---|
A 200-line React component with state, effects, and JSX. | A 15-line SCN block showing its props, | ~92% |
A 5-file utility library with complex internal logic. | A 25-line SCN graph showing public exports | ~85% |
By providing an SCN map to an LLM instead of raw code, you can fit 10-20x more relevant context into a single prompt, eliminating hallucinations and enabling the AI to reason about your entire project architecture.
For the complete specification, please see the Official SCN Spec v1.0.
->
) and call sites (<-
).class
, interface
, type
, enum
, and complex generic types.scn.config.js
file to define include/exclude patterns, project paths, and more.scn-js
is a development dependency, as it's part of your development and build process.
# Using Bun
bun i -D scn-js
# Using NPM
npm install --save-dev scn-js
# Using Yarn
yarn add --dev scn-js
The easiest way to get started is to run scn-js
from the command line in the root of your project.
Navigate to your project directory.
Run the generator:
npx scn-js "src/**/*.{ts,tsx,js,jsx}" --output context.scn
This command will:
.ts
, .tsx
, .js
, and .jsx
files inside your src/
directory.context.scn
file in your project root containing the complete SCN map.You can now copy the contents of context.scn
and paste it at the beginning of your LLM prompt to provide massive, high-quality context.
scn-js
is not a simple regex-based tool. It performs a deep, semantic analysis of your code using the same technology that powers your IDE and the TypeScript compiler.
◇
), functions (~
), interfaces ({}
), type aliases (=:
), enums (☰
), and top-level variables (@
). Each entity is assigned a unique, stable ID like (file_id.entity_id)
.import
/export
statements, function calls, and new
expressions to build the dependency graph, creating the crucial ->
(dependency) and <-
(caller) links between entities.This two-pass approach ensures that all relationships can be resolved, even with complex circular dependencies between files.
Source Code (src/services/auth.ts
, 86 tokens):
import { Database } from '../db';
import { User } from '../models/user';
export class AuthService {
private db: Database;
constructor(db: Database) {
this.db = db;
}
/**
* Logs a user in.
* @throws {Error} if login fails.
*/
public async login(email: string, pass: string): Promise<User> {
// ... complex implementation details ...
if (!email) throw new Error("Email required");
return {} as User;
}
}
Generated SCN (context.scn
, 24 tokens - 72% reduction):
§ (1) src/services/auth.ts
-> (db.ts), (models/user.ts)
◇ (1.1) AuthService
- @ db: #(Database)
+ ~ login(email: #, pass: #): #(User) ...!
Analysis: The SCN captures the public API (+ ~ login
), its async nature (...
), its potential to throw an error (!
), its private field (- @ db
), and its file-level dependencies, all while discarding the noisy implementation logic.
Source Code (src/components/ProfileCard.tsx
, 68 tokens):
import './ProfileCard.css';
interface ProfileCardProps {
userId: string;
onFollow: (id: string) => void;
}
export const ProfileCard = ({ userId, onFollow }: ProfileCardProps) => {
return (
<div className="profile-card" onClick={() => onFollow(userId)}>
<img className="profile-avatar" />
<p>User ID: {userId}</p>
</div>
);
};
Generated SCN (context.scn
, 31 tokens - 54% reduction):
§ (2) src/components/ProfileCard.tsx
-> (ProfileCard.css)
{ (2.1) ProfileCardProps
@ userId: #(string)
@ onFollow: #(function)
}
◇ (2.2) ProfileCard { props:#(2.1) }
⛶ (2.3) div [ class:.profile-card ]
⛶ (2.4) img [ class:.profile-avatar ]
⛶ (2.5) p
Analysis: scn-js
understands JSX. It maps the props interface ({}
), the component itself (◇
), and the HTML-like element tree (⛶
). It even notes the className
attributes, which are crucial clues for an LLM when asked to modify styling.
src/utils/string.ts
:
export const capitalize = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);
src/user/service.ts
:
import { capitalize } from '../utils/string';
export function formatUserName(name: string) {
return capitalize(name);
}
Generated SCN (context.scn
, 26 tokens):
§ (3) src/utils/string.ts
<- (4.1)
+ ~ (3.1) capitalize(s: #): #(string)
§ (4) src/user/service.ts
-> (3.1)
+ ~ (4.1) formatUserName(name: #)
-> (3.1)
Analysis: This demonstrates the core power of SCN. The <- (4.1)
link on capitalize
tells the LLM that formatUserName
uses it. The -> (3.1)
link on formatUserName
explicitly shows the dependency. The LLM can now trace logic across the entire codebase without needing to see the source of both files simultaneously.
scn.config.js
)For more control, you can create a scn.config.js
file in your project root.
// scn.config.js
module.exports = {
/**
* Path to your tsconfig.json file.
* This is highly recommended for TypeScript projects to ensure
* correct type analysis and path alias resolution.
*/
project: './tsconfig.json',
/**
* An array of glob patterns to include.
* @default ["**/*.{js,ts,jsx,tsx}"]
*/
include: [
'src/**/*.{ts,tsx}',
'lib/**/*.ts',
],
/**
* An array of glob patterns to exclude.
* node_modules and output file are always excluded.
* @default ["**/*.d.ts", "**/*.test.ts", "**/*.spec.ts"]
*/
exclude: [
'src/generated/**/*',
'**/*.stories.tsx',
],
/**
* The path to the output SCN file.
* @default "context.scn"
*/
output: 'ai-context.scn',
};
scn-js
will automatically detect and use this configuration file if it exists.
You can override any configuration setting with command-line flags.
npx scn-js [globs...] [options]
Arguments:
[globs...]
: (Optional) Space-separated glob patterns. If provided, they override the include
setting in the config file.Options:
Flag | Alias | Description |
---|---|---|
--output <path> | -o | Specify the output file path. |
--project <path> | -p | Path to the tsconfig.json . Essential for TS projects. |
--watch | -w | Watch files for changes and re-generate SCN automatically. |
--config <path> | -c | Path to a custom config file. |
--version | -v | Display the version number. |
--help | -h | Display the help screen. |
For advanced integrations, you can use scn-js
as a library.
import { generateScn } from 'scn-js';
import path from 'path';
async function buildAiContext() {
try {
const scnOutput = await generateScn({
// Options are identical to the config file
project: path.resolve(__dirname, 'tsconfig.json'),
include: ['src/**/*.{ts,tsx}'],
exclude: ['**/*.spec.ts'],
});
console.log('Generated SCN Map:');
console.log(scnOutput);
// Or write it to a file
// await fs.promises.writeFile('context.scn', scnOutput, 'utf-8');
} catch (error) {
console.error('Failed to generate SCN:', error);
}
}
buildAiContext();
To enhance the SCN output, scn-js
recognizes specific JSDoc tags to add function qualifiers:
!
(Throws): Add @throws
to your function's JSDoc to indicate it can throw an error.
/** @throws {AuthError} If the user is not found. */
function findUser() { /* ... */ }
// SCN: ~ findUser() !
o
(Pure): Add @pure
to your function's JSDoc to indicate it has no side effects. This is a powerful hint for an LLM.
/** @pure */
function calculateTotal(items) { /* ... */ }
// SCN: ~ calculateTotal(items: #) o
The SCN standard and the scn-js
tool are actively evolving. We welcome community contributions.
scn-js
Roadmap:
<-
) to trace function usage within other function bodies.How to Contribute:
This project is licensed under the MIT License. See the LICENSE file for details.
FAQs
[](https://www.npmjs.com/package/scn-js) [](https://github.com/scn-lang/scn) [![Build Status](https://img.shields.io/github/action
The npm package scnjs receives a total of 1 weekly downloads. As such, scnjs popularity was classified as not popular.
We found that scnjs demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
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.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.
Security News
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.