Agent skill

Sasjs Framework

by sasjs in sasjs/core

Building full SASjs applications - project structure, sasjsconfig.json, services/jobs/macros folders, multi-target (SAS 9 / Viya / SASjs server) configuration, streaming frontends, mocks and tests.

MITAuto-check passedFrontend & Design

Install Sasjs Framework

skills CLI
$ npx skills add sasjs/core --skill sasjs-framework -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install sasjs/core sasjs-framework --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/sasjs/core.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/sasjs-framework .claude/skills/sasjs-framework && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
sasjs-framework
GitHub stars
132
Token cost
~2.4k tokens
SKILL.md length
1,091 words
Files
2
Skills in repo
6
Repo updated
First seen
Licence
MIT

At a glance

Building full SASjs applications - project structure, sasjsconfig.json, services/jobs/macros folders, multi-target (SAS 9 / Viya / SASjs server) configuration, streaming frontends, mocks and tests.

  • Works in 5 steps: Adapter POSTs to services// with input… → Service SAS code runs after initProgram;… → Conventional pattern using @sasjs/core… → …
  • Modifying a SASjs app
  • SKILL.md covers Standard project layout, sasjsconfig.json, Streamed frontend files on… and Service contract (frontend <->…, plus 6 more sections
  • Reaches cli.sasjs.io

What it does

Sasjs Framework is an agent skill from sasjs/core. Building full SASjs applications - project structure, sasjsconfig.json, services/jobs/macros folders, multi-target (SAS 9 / Viya / SASjs server) configuration, streaming frontends, mocks and tests. Use when creating or modifying a SASjs app, editing sasjsconfig.json, or writing backend services returning JSON to a web frontend.

Its SKILL.md is about 2.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `sasjsconfig-schema.json`).

It sits in Frontend & Design. The repository describes itself as: Macros for SAS® App Developers. The licence is MIT.

When your agent uses it

  • Modifying a SASjs app
  • Editing sasjsconfig.json
  • Writing backend services returning JSON to a web frontend

Example prompts

  • “/sasjs-framework”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Adapter POSTs to services// with input tables (arrays of objects) -> work datasets named after the JS keys.
  2. Service SAS code runs after initProgram; it reads inputs, does work, and writes output JSON to _webout.
  3. Conventional pattern using @sasjs/core macros
  4. The SAS Macros @li entries in the header are not documentation - they are the compiler's dependency manifest. Every macro the service…
  5. On error, abort cleanly with %mp_abort(...) (mf_abort is deprecated) so the adapter receives a structured error in the JSON, not a…

What it can do on your machine

Read from SKILL.md and the folder at commit b13a83f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are sas).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • cli.sasjs.io

    Also links to:

    • github.com
    • git.datacontroller.io

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Sasjs Framework loads about 2.4k tokens when it runs. Until then it costs about 86 tokens; SKILL.md has 1,091 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~86
When it runs · the whole SKILL.md, loaded when a task matches
~2.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from sasjs/core at commit b13a83f, republished under its MIT licence (© sasjs). 1,091 words, ~2,413 tokens.

Download SKILL.mdSave it as .claude/skills/sasjs-framework/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
sasjs-framework
description
Building full SASjs applications - project structure, sasjsconfig.json, services/jobs/macros folders, multi-target (SAS 9 / Viya / SASjs server) configuration, streaming frontends, mocks and tests. Use when creating or modifying a SASjs app, editing sasjsconfig.json, or writing backend services returning JSON to a web frontend.

SASjs Framework - Building SASjs Applications

A SASjs app = a web frontend (any framework: Angular, React, vanilla) + SAS backend code organised in a standard layout, compiled and deployed by @sasjs/cli to SAS 9, Viya, or SASjs server. Frontend talks to SAS via @sasjs/adapter; backend services return JSON via _webout.

Standard project layout

sasjs/
  sasjsconfig.json     # project + target configuration
  macros/              # project-specific macros (macroFolders)
  services/            # web services called from the frontend
  jobs/                # jobs (scheduled / flow / long-running)
  programs/            # plain programs (initProgram, termProgram, utilities)
  db/                  # DDL + static data per library (sasjs db)
  tests/               # tests run by `sasjs test`
  mocks/               # mock responses for offline frontend dev (syncFolder)
  doxy/                # extra doxygen content for `sasjs doc`

sasjsconfig.json

Root config holds defaults; each entry in targets[] can override them. Key sections:

  • macroFolders, binaryFolders - where the CLI finds macros/binaries
  • serviceConfig.serviceFolders - service source folders; initProgram runs before every service (set up libnames, options)
  • jobConfig.jobFolders - job source folders
  • programFolders - programs compiled/deployed with the app
  • streamConfig - streamWeb: true streams the built frontend into SAS so it is served by the platform itself (no separate web server needed); webSourcePath points at the frontend build output
  • syncFolder - folder synced to the server (e.g. mocks)
  • testConfig - init/term programs for sasjs test
  • targets[] - per-environment overrides: serverUrl, serverType (SAS9/SASVIYA/SASJS), appLoc (deploy root, e.g. /Public/app/myapp), target-specific macroFolders (e.g. targets/viya/macros_viya for platform shims), httpsAgentOptions, deployConfig

The full JSON schema is bundled at sasjsconfig-schema.json next to this file - validate config changes against it. Reference it with "$schema": "https://cli.sasjs.io/sasjsconfig-schema.json".

Streamed frontend files on Viya (mime types)

When streamWeb: true, the CLI uploads the frontend (index.html, renamed per streamServiceName, plus css/js) to the Viya Files service using the %mv_createfile macro. That macro creates the file in a very particular way to ensure it streams correctly:

  • POSTs to /files/files with the content type derived from the extension (%mf_mimetype)
  • sets typeDefName=file_html (via %mv_getViyaFileExtParms) so the file is recognised as HTML
  • sends Content-Disposition without attachment for HTML/SVG so it renders in the browser

Never update a streamed frontend file in place with a filename filesrvc fileref + data step rewrite - the Files service then treats it as a generic blob and the mime type is lost, so the app no longer streams (browser downloads it or shows raw text). To modify a streamed file at runtime (eg patching the compute contextname in the html), read it (a filesrvc fileref is fine for reading), write the modified content to a temp fileref, and re-create the file with %mv_createfile(path=..., name=..., inref=...) (it deletes the old file and re-POSTs with the correct mime type).

Service contract (frontend <-> SAS)

  1. Adapter POSTs to services/<folder>/<name> with input tables (arrays of objects) -> work datasets named after the JS keys.
  2. Service SAS code runs after initProgram; it reads inputs, does work, and writes output JSON to _webout.
  3. Conventional pattern using @sasjs/core macros:
sas
/**
  @file
  @brief Example service returning data
  <h4> SAS Macros </h4>
  @li mp_jsonout.sas
  @li mp_abort.sas
**/

/* validation / logic here */

%mp_jsonout(OPEN)
%mp_jsonout(OBJ,results,dslabel=results)
%mp_jsonout(CLOSE)
  1. The <h4> SAS Macros </h4> @li entries in the header are not documentation - they are the compiler's dependency manifest. Every macro the service calls must be listed there or it is not inlined into the build and the deployed job fails at runtime with Apparent invocation of macro X not resolved. Undeclared calls can pass testing by accident when a declared macro's own @li chain happens to inline them (transitive resolution), then break when that macro's dependencies change. When editing an existing service, re-audit the %macro() calls in the body against the header entries and declare anything missing - including small helpers like mf_getuser.sas.

  2. On error, abort cleanly with %mp_abort(...) (mf_abort is deprecated) so the adapter receives a structured error in the JSON, not a half-written response. Do not call %mp_abort inside an %if/%else block - the macro processor may keep executing beyond the abort. Use the conditional iftrue= parameter instead, e.g.:

sas
%mp_abort(iftrue= (%mf_existds(work.results)=0)
  ,mac=&_program
  ,msg=%str(No results found)
)

If the abort happens inside a %include block, SAS cannot exit to _webout cleanly - after the include, call %mp_abort(mode=INCLUDE) (outside any macro wrapper), which checks work.mp_abort_errds for an abort status.

Show full SKILL.md (506 more words)Show less

Sanitising service inputs (SAS macro injection)

Every value arriving from the web request (input tables, url params) is attacker-controlled. If it is resolved as a macro variable inside generated code - a libname path, a set/from statement, a where clause, a %include - then spaces, quotes, semicolons and &/% macro triggers become classic SAS injection vectors.

Rules:

  • Validate inputs in a data step with %mp_validatecol(incol,RULE,outcol) from @sasjs/core before any call symputx. Only symput on pass; abort otherwise (%mp_abort(iftrue=...)). Rules include ISLIB (valid libref), ISNAME (valid SAS name, eg a member/table name), LIBDS (LIBREF.DATASET), FORMAT, ISINT, ISNUM.
  • Where a whitelist exists, use it: after syntactic validation, confirm the value exists in a control table (eg a primary-key lookup) before using it to build paths or code.
  • Values read back from control tables can also be tampered with - validate those too before passing them into code-generating macros.
  • For free-text values that must be echoed into code (eg a user message), strip macro triggers: compress(value,'&%;') or tranwrd each dangerous char - but prefer not to place free text in code at all.
sas
%let libds=0;
data _null_;
  set work.sascontroltable;
  %mp_validatecol(libds,LIBDS,is_libds)
  if is_libds=1 then call symputx('libds',libds);
  else putlog 'ERR' 'OR: invalid libds: ' libds;
run;
%mp_abort(iftrue= ("&libds"="0")
  ,mac=&_program
  ,msg=%str(Invalid libds provided)
)

Multi-target discipline

  • Keep backend code platform-neutral in shared folders; put platform-specific shims in targets/<name>/macros_* folders and register them only on that target.
  • Platform capability macros exist in @sasjs/core (mm_* metadata, mv_* Viya, ms_* server) - don't branch on server type by hand.

Quality gates (follow the conventions of mature apps like Data Controller)

  • Run sasjs lint after touching any .sas file; fix all warnings in files you touched.
  • The linter enforces 2-space indentation everywhere, including continuation lines inside /* ... */ block comments - never align comment text with 3+ spaces.
  • Add tests and run sasjs test for backend logic changes. When testing macros, always wrap the macro under test with %mp_assertscope(SNAPSHOT) / %mp_assertscope(COMPARE, ...) to catch macro-variable scope leakage, and wrap any platform-branching code in %macro wrappers (no open conditional macro code in test programs).
  • Provide mocks in sasjs/mocks so the frontend can be developed without a live SAS server.
  • Never auto-commit or bump versions; releases are pipeline-driven (conventional commits).
  • Markdown files: no hard wrapping - one paragraph per line.
  • Apps must work offline/on-prem: no external CDN assets in the frontend bundle.

Tests must be idempotent

A test file must pass when run repeatedly (including after a run that failed partway).

  • Start the file with %let syscc=0; - many DC macros abort on entry if &syscc>0, and any WARNING in a previous test bumps syscc to 4.
  • Make prep defensive: delete-then-insert config records (handles leftovers from an aborted run), and recreate physical tables rather than assuming they are absent.

Reference implementations

Look at existing apps for patterns: folder layouts, sasjsconfig.json multi-target setups, service structure, streaming builds, and test/mock conventions, eg:

Limitations

This skill is a static reference for building SASjs applications - it provides guidance on project structure, configuration, and service contracts. It does not execute code, run shell commands, access the filesystem, connect to databases, or make network requests. References to file paths, build outputs, and deployment targets describe the structure of a SASjs project - this skill does not create, modify, or access those paths itself.

© sasjs, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in .agents/skills/sasjs-framework of sasjs/core.

  • SKILL.md
  • sasjsconfig-schema.json

Open the folder on GitHubat commit b13a83f

Compare with similar skills

Sasjs Framework next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Sasjs Framework compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Sasjs Framework this skillsasjs/core132—~2.4kAutomated safety check: PassMIT
Web Artifacts Builderanthropics/skills180k41 repos~769Automated safety check: PassApache-2.0
React Doctormakeplane/plane61k12 repos~657Automated safety check: PassAGPL-3.0
Impeccablebestofjs/bestofjs3.1k27 repos~2.6kAutomated safety check: PassMIT
Figma Design System Builderwarpdotdev/warp65k2 repos~4.4kAutomated safety check: PassAGPL-3.0
Web Interface Guidelines Reviewervercel-labs/openreview1.7k98 repos~308Automated safety check: PassNone

Similar skills

  • Web Artifacts Builder

    anthropics/skills

    Official

    Builds multi-component claude.ai HTML artifacts as a small React, TypeScript and Tailwind project, then bundles it into one shareable HTML file.

    180k GitHub starsUsed in 41 repos~769 tokens
    Frontend & DesignAuto-check passed
  • React Doctor

    makeplane/plane

    Scans React code for lint, accessibility, bundle size and architecture issues, reports a health score and checks that changes do not lower it.

    61k GitHub starsUsed in 12 repos~657 tokens
    Frontend & DesignAuto-check passed
  • Impeccable

    bestofjs/bestofjs

    A skill your agent uses when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a…

    3.1k GitHub starsUsed in 27 repos~2.6k tokens
    Frontend & DesignAuto-check passed
  • Builds or updates a design system in Figma from a codebase in ordered phases: discovery, variables and tokens, components, theming and documentation, with checkpoints.

    65k GitHub starsUsed in 2 repos~4.4k tokens
    Frontend & DesignAuto-check passed
  • Web Interface Guidelines Reviewer

    vercel-labs/openreview

    Official

    Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my…

    1.7k GitHub starsUsed in 98 repos~308 tokens
    Frontend & DesignAuto-check passed
  • Tailwindcss Development

    anonaddy/anonaddy

    Always invoke when the user's message includes 'tailwind' in any form.

    4.9k GitHub starsUsed in 10 repos~865 tokens
    Frontend & DesignAuto-check passed

More from sasjs/core

  • Sas

    sasjs/core

    Expert guidance for the SAS programming language - DATA step, PROC SQL, macro language, formats, ODS, and common procedures.

    132 GitHub stars~3.1k tokensUpdated 3 days ago
    Auto-check passed
  • Sasjs Adapter

    sasjs/core

    Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management.

    132 GitHub stars~2.6k tokensUpdated 3 days ago
    Auto-check passed
  • Sasjs CLI

    sasjs/core

    Using the SASjs CLI (@sasjs/cli) to create, compile, build, deploy, run, and test SASjs projects against SAS 9, Viya, and SASjs server targets.

    132 GitHub stars~3.6k tokensUpdated 3 days ago
    Auto-check: notes
  • Sasjs Core

    sasjs/core

    Standards and conventions for the @sasjs/core SAS macro library (mf, mp, mm, ms, mv macros).

    132 GitHub stars~1.2k tokensUpdated 3 days ago
    Auto-check passed
  • Sasjs Server

    sasjs/core

    Installing, configuring, and running @sasjs/server - the open-source NodeJS wrapper around the SAS binary that provides a REST API, filesystem (SASjs Drive), Stored Program execution, and web app…

    132 GitHub stars~2.4k tokensUpdated 3 days ago
    Auto-check: notes

Questions about Sasjs Framework

What does Sasjs Framework do?

Building full SASjs applications - project structure, sasjsconfig.json, services/jobs/macros folders, multi-target (SAS 9 / Viya / SASjs server) configuration, streaming frontends, mocks and tests. Sasjs Framework is an agent skill from sasjs/core.json, services/jobs/macros folders, multi-target (SAS 9 / Viya / SASjs server) configuration, streaming frontends, mocks and tests.

When should I use Sasjs Framework?

Sasjs Framework fits situations like: modifying a SASjs app; editing sasjsconfig.json; writing backend services returning JSON to a web frontend.

How do I install Sasjs Framework in Claude Code?

Run `npx skills add sasjs/core --skill sasjs-framework -a claude-code`. Or copy the skill folder (.agents/skills/sasjs-framework in sasjs/core) into .claude/skills/sasjs-framework in your project. Claude Code loads it when a task matches its description.

How do I install Sasjs Framework in Codex?

Run `npx skills add sasjs/core --skill sasjs-framework -a codex`. Or copy the skill folder (.agents/skills/sasjs-framework in sasjs/core) into .agents/skills/sasjs-framework in your project. Codex loads it when a task matches its description.

Can I use Sasjs Framework in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add sasjs/core --skill sasjs-framework -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/sasjs-framework, .gemini/skills/sasjs-framework, .github/skills/sasjs-framework and .opencode/skills/sasjs-framework in your project.

What does Sasjs Framework need to run?

SKILL.md names no scripts, command-line tools or credentials: Sasjs Framework is instructions for the agent only.

Does Sasjs Framework access the network?

SKILL.md names 3 domains. In commands or code: cli.sasjs.io; the agent is likely to contact it when it follows the instructions. As links in the text: github.com and git.datacontroller.io. This is read from the text; nothing was executed.

Is Sasjs Framework safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Sasjs Framework use?

Sasjs Framework is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Sasjs Framework use?

About 2.4k tokens (SKILL.md is roughly 9.7k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Sasjs Framework?

Skills that share tags, products or a category with Sasjs Framework: Web Artifacts Builder (anthropics/skills, 180k stars), React Doctor (makeplane/plane, 61k stars), Impeccable (bestofjs/bestofjs, 3.1k stars) and Figma Design System Builder (warpdotdev/warp, 65k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Sasjs Framework?

sasjs (a GitHub organization) maintains it in sasjs/core, which has 132 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 5, 2026.

Source: sasjs/core on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.