Web Artifacts Builder
anthropics/skills
Builds multi-component claude.ai HTML artifacts as a small React, TypeScript and Tailwind project, then bundles it into one shareable HTML file.
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.
$ npx skills add sasjs/core --skill sasjs-framework -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install sasjs/core sasjs-framework --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ 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-srcUse ~/.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/
Install the "sasjs-framework" agent skill from https://github.com/sasjs/core/tree/main/.agents/skills/sasjs-framework into .claude/skills/sasjs-framework/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sasjs-framework", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/sasjs/core/tree/main/.agents/skills/sasjs-frameworkType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add sasjs/core --skill sasjs-framework -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install sasjs/core sasjs-framework --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sasjs/core.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/sasjs-framework .agents/skills/sasjs-framework && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "sasjs-framework" agent skill from https://github.com/sasjs/core/tree/main/.agents/skills/sasjs-framework into .agents/skills/sasjs-framework/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sasjs-framework", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add sasjs/core --skill sasjs-framework -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install sasjs/core sasjs-framework --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sasjs/core.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/sasjs-framework .cursor/skills/sasjs-framework && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "sasjs-framework" agent skill from https://github.com/sasjs/core/tree/main/.agents/skills/sasjs-framework into .cursor/skills/sasjs-framework/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sasjs-framework", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/sasjs/core.git --path .agents/skills/sasjs-framework--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add sasjs/core --skill sasjs-framework -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install sasjs/core sasjs-framework --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sasjs/core.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/sasjs-framework .gemini/skills/sasjs-framework && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "sasjs-framework" agent skill from https://github.com/sasjs/core/tree/main/.agents/skills/sasjs-framework into .gemini/skills/sasjs-framework/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sasjs-framework", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install sasjs/core sasjs-frameworkInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add sasjs/core --skill sasjs-framework -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/sasjs/core.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/sasjs-framework .github/skills/sasjs-framework && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "sasjs-framework" agent skill from https://github.com/sasjs/core/tree/main/.agents/skills/sasjs-framework into .github/skills/sasjs-framework/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sasjs-framework", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add sasjs/core --skill sasjs-framework -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install sasjs/core sasjs-framework --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sasjs/core.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/sasjs-framework .opencode/skills/sasjs-framework && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "sasjs-framework" agent skill from https://github.com/sasjs/core/tree/main/.agents/skills/sasjs-framework into .opencode/skills/sasjs-framework/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sasjs-framework", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
sasjs-frameworkBuilding 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. 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.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit b13a83f. It shows what the files ask for, not the result of running them.
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.
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.
Hosts in commands or code, which the agent is likely to contact:
cli.sasjs.ioAlso links to:
github.comgit.datacontroller.ioFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
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.
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.
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.
The full file from sasjs/core at commit b13a83f, republished under its MIT licence (© sasjs). 1,091 words, ~2,413 tokens.
.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.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.
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`Root config holds defaults; each entry in targets[] can override them. Key sections:
macroFolders, binaryFolders - where the CLI finds macros/binariesserviceConfig.serviceFolders - service source folders; initProgram runs before every service (set up libnames, options)jobConfig.jobFolders - job source foldersprogramFolders - programs compiled/deployed with the appstreamConfig - 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 outputsyncFolder - folder synced to the server (e.g. mocks)testConfig - init/term programs for sasjs testtargets[] - 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, deployConfigThe 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".
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:
/files/files with the content type derived from the extension (%mf_mimetype)typeDefName=file_html (via %mv_getViyaFileExtParms) so the file is recognised as HTMLContent-Disposition without attachment for HTML/SVG so it renders in the browserNever 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).
services/<folder>/<name> with input tables (arrays of objects) -> work datasets named after the JS keys.initProgram; it reads inputs, does work, and writes output JSON to _webout./**
@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)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.
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.:
%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.
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:
%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.compress(value,'&%;') or tranwrd each dangerous char - but prefer not to place free text in code at all.%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)
)targets/<name>/macros_* folders and register them only on that target.mm_* metadata, mv_* Viya, ms_* server) - don't branch on server type by hand.sasjs lint after touching any .sas file; fix all warnings in files you touched./* ... */ block comments - never align comment text with 3+ spaces.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).sasjs/mocks so the frontend can be developed without a live SAS server.A test file must pass when run repeatedly (including after a run that failed partway).
%let syscc=0; - many DC macros abort on entry if &syscc>0, and any WARNING in a previous test bumps syscc to 4.Look at existing apps for patterns: folder layouts, sasjsconfig.json multi-target setups, service structure, streaming builds, and test/mock conventions, eg:
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
SKILL.md and 1 other file in .agents/skills/sasjs-framework of sasjs/core.
Open the folder on GitHubat commit b13a83f
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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Sasjs Framework this skillsasjs/core | 132 | — | ~2.4k | Automated safety check: Pass | MIT | |
| Web Artifacts Builderanthropics/skills | 180k | 41 repos | ~769 | Automated safety check: Pass | Apache-2.0 | |
| React Doctormakeplane/plane | 61k | 12 repos | ~657 | Automated safety check: Pass | AGPL-3.0 | |
| Impeccablebestofjs/bestofjs | 3.1k | 27 repos | ~2.6k | Automated safety check: Pass | MIT | |
| Figma Design System Builderwarpdotdev/warp | 65k | 2 repos | ~4.4k | Automated safety check: Pass | AGPL-3.0 | |
| Web Interface Guidelines Reviewervercel-labs/openreview | 1.7k | 98 repos | ~308 | Automated safety check: Pass | None |
anthropics/skills
Builds multi-component claude.ai HTML artifacts as a small React, TypeScript and Tailwind project, then bundles it into one shareable HTML file.
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.
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…
warpdotdev/warp
Builds or updates a design system in Figma from a codebase in ordered phases: discovery, variables and tokens, components, theming and documentation, with checkpoints.
vercel-labs/openreview
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my…
anonaddy/anonaddy
Always invoke when the user's message includes 'tailwind' in any form.
sasjs/core
Expert guidance for the SAS programming language - DATA step, PROC SQL, macro language, formats, ODS, and common procedures.
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.
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.
sasjs/core
Standards and conventions for the @sasjs/core SAS macro library (mf, mp, mm, ms, mv macros).
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…
Categories
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.
Sasjs Framework fits situations like: modifying a SASjs app; editing sasjsconfig.json; writing backend services returning JSON to a web frontend.
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.
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.
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.
SKILL.md names no scripts, command-line tools or credentials: Sasjs Framework is instructions for the agent only.
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.
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.
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.
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.
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.
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.