@slicerx/settings (TypeScript) and sx-settings (Rust) read the same data files: the schema, the Easy mode map and the profile import rules. This guide shows how to use them. The reference lists every setting with neutral wording;
Keys and values
Keys are OrcaSlicer's own names, so an Orca or Bambu Studio profile imports without translation. A PrintConfig is a plain object from key to typed value.
- Numbers are numbers. Percent settings hold the number (
15means 15%). - Settings that take millimeters or a percent (line widths) hold Orca's string, such as
"0.42"or"110%"."0"means automatic. - Many speed, temperature and fan settings are lists with one entry per extruder or hotend flavor. A profile stores
["220"]; you get[220]. Lists stay lists when you change them. - A key set to
nilin a profile means "take it from another profile". It is left out of the config and listed innilKeys.
The base schema has neutral labels and no help text, so it works on its own. A host that has its own labels and help text can lay them over the schema with registerSettingText. Each schema entry (SettingDef) has the key, section (process, filament or printer), type, unit, default, a recommended range (min, max), Orca's own limits when they differ (orcaMin, orcaMax), enum values, a label and help text, a group, enabledWhen conditions, the first slice stage a change redoes (invalidates), an easy flag and the PrintPilot class (pilot).
import { SETTINGS, settingDef, isEnabled } from '@slicerx/settings'
const def = settingDef('sparse_infill_density')
def?.label // "Infill density"
isEnabled(settingDef('sparse_infill_pattern')!, config) // false while density is 0Our own profiles
SlicerX ships printer, filament and process profiles of its own, written from the makers' published specs and the cited knowledge base (no Orca files are inputs).
import { listPrinterProfiles, printerProfile, printerConfig, filamentConfig, listProcessPresets, processConfig, profileConfig, searchProfiles } from '@slicerx/settings'
printerProfile('bambu-x1-carbon') // build volume, nozzles, flavor, limits, the maker pages it follows
listProcessPresets(0.4) // 0.28 mm Draft, 0.20 mm Standard, 0.12 mm Fine, 0.08 mm Extra fine, 0.20 mm Strong
const config = profileConfig({ printer: 'prusa-mk4s', nozzle: 0.6, filament: 'petg', process: 'standard' })
await searchProfiles('bambo lab') // fuzzy search by vendor and model, for first-run setup- Printer profiles: one per model in
@slicerx/printer-catalog, keyed by the catalog's model id.profiles/printers.jsonis generated bynode scripts/gen-profiles.mjsfrom the catalog,scripts/printer-specs.json(G-code flavor and the maker's page) andknowledge.json(the limits the makers publish, for the models the knowledge base covers).printerConfig(id, nozzle)gives the bed shape and height, flavor, extruder type, machine limits and the layer height limits for the nozzle. - Filament profiles: one per material in
knowledge/filaments.filamentConfig(id)gives the temperatures, cooling, flow, retraction and pressure advance the knowledge base cites, andfilamentSources(id)lists the sources. - Filament presets per brand:
listFilamentFamilies,filamentBrandsandloadFilamentPreset(vendor, family, variant)give the makers' own filament values (5776 presets from Bambu Studio and OrcaSlicer, seedocs/filament-presets.md). Rust reads a vendor file withVendorFile::parse. They are separate from the 20 knowledge based materials thatplanSettingsandfilamentConfiguse. - Machine settings: 49 of the 57 models have the maker's own numbers and choices in
profiles/machine.json(bed shape and origin, printable height, machine limits per axis, retraction and z hop defaults, extruder offsets and clearance, thumbnails, G-code flavor and the rest), with the version they were checked against.printerConfigapplies them, per nozzle where the maker has a profile for it.docs/printer-profiles.mdlists each model, andjs/machine.test.tslocks the values. Every printer setting is advanced or expert in the schema, so casual users never see them. The four levels aresimple,advanced,expert(Orca's expert tier) anddevelop. - G-code:
profiles/gcode.jsonholds start, end, layer change and filament change G-code per printer family: the makers' own templates (maker_*) and ones written for SlicerX. Every model gets the five G-code keys in its printer config. - Process speeds:
processConfig(tier, nozzle, printer)takes the speeds, accelerations and jerk from the maker's own preset for that printer and tier (profiles/process-speeds.json, 49 models) on the 0.4 mm nozzle, and the plain process otherwise. The Fine tier of the Bambu P2S and H2 family adds tuned quality values (outer wall 50 on the standard hotend, moderate overhang speeds, a smoother support underside). - Process presets: the quality tiers Draft, Standard, Fine, Extra fine and Strong for a nozzle, made by the Easy mode map from a plain process.
profileConfigmerges process, filament and printer (later wins). - Rust has the same functions (
printer_config,filament_config,process_config,profile_config, ...).fixtures/profiles-golden.jsonholds hashes both languages must match.
Import a profile
Reading a user's own Orca or Bambu Studio profile is file interop. Those profiles have an inherits chain. importOrcaProfile(json, resolve) takes the profile JSON and a function that finds a parent by name.
import { importOrcaProfile, mergeConfigs } from '@slicerx/settings'
const process = importOrcaProfile(userProcessJson, (name) => findParent(name))
process.chain // profile, then each parent up to the root
process.unknownKeys // keys neither the schema nor the legacy rules know
const config = mergeConfigs(printer.config, filament.config, process.config)use sx_settings::{import_orca, PrintConfig};
let imported = import_orca(&profile_json, &|name| load_parent(name))?;
let config = PrintConfig::merged(&[&printer.config, &filament.config, &imported.config]);Legacy key names and values from older Orca and Bambu Studio files are translated on import; keys only Bambu Studio and other forks define are reported in ignoredKeys, not as unknown.
use sx_settings::{import_profile_json, import_project_json};
// A profile the user supplied, with its parents (found by name).
let imported = import_profile_json(r#"{ "profile": { "name": "My PLA", "inherits": "Base PLA", "nozzle_temperature": ["215"] },
"parents": [ { "name": "Base PLA", "type": "filament", "filament_type": ["PLA"] } ] }"#)?;
// The settings inside a project: the contents of the three metadata files.
let project = import_project_json(&serde_json::json!({ "projectSettings": settings_json, "modelSettings": model_xml }).to_string())?;To read the settings inside a .3mf project, pass the parsed Metadata/project_settings.config (and, if you have them, the text of model_settings.config and layer_config_ranges.xml) to importProject. It returns the config, per object and per part overrides, plates and layer ranges.
Easy mode
Easy mode maps a few controls to concrete settings: Detail and Strength sliders, a Speed preset, Supports and Brim. The map is easy-map.json; both languages interpret it.
import { applyEasy, goalEasy } from '@slicerx/settings'
const easy = goalEasy('fine') // or { detail: 40, strength: 20, speed: 'standard', supports: 'auto', brim: true }
const next = applyEasy(easy, config)use sx_settings::{apply_easy, goal_easy, EasyGoal};
let next = apply_easy(&goal_easy(EasyGoal::Fine), &config);Pass the unmodified merged profile as the base. Speed scaling multiplies the base values, so applying Easy twice to an already scaled config scales twice. Layer height scales with the nozzle, and a speed increase never exceeds the filament's flow limit or the machine's acceleration limit.
Smart Layer
Smart Layer is automatic variable layer height. Its keys are our own, in the process section: smart_layer (off, quality or strength, shown as Off, Smart Layer: Quality and Smart Layer: Strength), smart_layer_min_height and smart_layer_max_height (the thinnest and thickest layer in mm), smart_layer_smoothing (percent, default 70), smart_layer_smoothing_radius (mm along the part height; 0 means eight times the thickest layer) and smart_layer_max_step_ratio (the biggest change between neighboring layers as a fraction of the previous one). The engine reads them; settings only defines, validates and plans them.
- The window is a share of the nozzle on the 0.02 mm step grid. Without a mode it is 25 to 75 percent (0.10 to 0.30 mm on a 0.4 mm nozzle). Each mode has its own band: Quality 20 to 50 percent and Strength 30 to 50 percent (0.08 to 0.20 mm and 0.12 to 0.20 mm on a 0.4 mm nozzle), intersected with the material's window for that mode when its research gives one, and never above 75 percent. Where the two do not overlap the material's window wins.
smartLayerWindow(nozzle, material?, mode?)gives the window andsmartLayerBounds({ nozzleDiameter, layerHeight?, material?, mode? })gives bounds around a layer height. - A material's research can change the share. A filament file under
knowledge/filamentsmay holdsmart_layer: { min_ratio, max_ratio, modes: { quality: {min_ratio, max_ratio}, strength: {...} }, note, src }(without it the material'slayer_height.fraction_of_nozzleband is used, never above 75 percent);pnpm gen:knowledgecompiles it,validate(config, { filament })andplanSettingsuse it, and the reason names the research. - Easy mode: the Smart Layer control is
smartLayerinEasySettings(off when absent). The Fine goal turns on Quality and the Strong goal turns on Strength. The Detail slider sets the bounds: they sit at about half to one and a half times the layer height it gives, inside the window, so a higher Detail narrows them. The bands ineasy-map.jsonare the mode bands without a material;planSettingsthen fits the bounds to the material's window for the mode. validatereports a window that is out of order (error), a thinnest layer under or a thickest layer over the window (warning, with a fix), Smart Layer in vase mode (warning), and a layer height outside the range (info).planSettingsscales the bounds when the nozzle changes and keeps them inside the window of the new nozzle and material.
Material limits in a plan
A filament file also carries a safe layer height band (layer_height.fraction_of_nozzle) and speed limits (speeds: the most the material prints at, an outer wall ceiling where the material itself caps it, and a first layer ceiling). planSettings treats them as bounds, not defaults: a layer height outside the band, or a speed above a ceiling, is moved to the nearest allowed value in the plan (per extruder lists element by element), and a goal that pushes past a bound is clamped and recorded in clamps. With Smart Layer on, the material's notes for Quality or Strength mode and for thin layer cooling come back in advice.
More material knowledge in the plan
- Minimum layer time guard: with Smart Layer on,
slow_down_layer_timeis raised to the family'scooling_guard(fromworkflows/techniques/smart_layer.yaml, compiled intocoolingGuard), the cooling slowdown is turned on if it was off, and the plan advises printing more parts at once.validate(config, { filament })reportssmart_layer_min_layer_timewith a fix. - Heat creep warning: a slowed layer that extrudes under 3.5 percent of the filament's maximum volumetric speed (
slow_down_min_speedtimes the wall width times the thinnest layer) adds a plan warning and theheat_creep_thin_layersissue. The threshold is an expert rule, not a cited fact; no maker publishes one (HEAT_CREEP_SHARE). It only warns and never changes settings. - Supports: with supports on and a material switch,
support_top_z_distanceandsupport_interface_top_layersfollow the material'ssupportsblock, andadvicenames the interface materials and the soluble partner. - First layer:
initial_layer_speed(and the fan off layers whencoolinghas none) come fromfirst_layer; the squish and bed notes come back as advice on a material switch. retraction_speedcomes fromextrusion.retraction_mm.retraction_speed_mm_son direct drive printers.structure(walls note, infill pattern hint and density note) comes back as advice on a material switch.
Catalog models
printerForModel(catalogModelId), modelsForPrinter(printerId) and setupForModel(catalogModelId, filament, nozzle?) map the printer catalog's model ids (bambu-x1-carbon) to the knowledge printer ids that SetupRef.printer uses (bambu_x1c). The table is printer-models.json; Rust has printer_for_model, models_for_printer and setup_for_model.
Validate
import { validate } from '@slicerx/settings'
for (const issue of validate(next)) console.log(issue.severity, issue.code, issue.message, issue.fix)validate checks types, ranges and enum values, then looks for conflicts between keys (layer height above the nozzle, spiral mode with supports, a speed the filament cannot melt fast enough, a temperature outside the filament range). Errors come first. A fix is a suggestion; nothing is applied for you. Conflict checks look only at keys the config sets.
Diff two configs
import { diffConfigs } from '@slicerx/settings'
const changes = diffConfigs(before, after, { easy })
// [{ key, label, before, after, stage, reason }, ...] earliest slice stage firststage is the first stage the change redoes, so a UI can tell how much of the slice to redo. The reason names the Easy control that drove the key, describes the effect of raising or lowering it, and says when a dependency switches the key off.
use sx_settings::diff_configs;
let changes = diff_configs(&before, &after, Some(&easy));Plan a material, printer or nozzle switch
planSettings works out what to change when the material, printer or nozzle changes, and can fold in goals. It is deterministic, needs no network and takes about a millisecond.
import { planSettings, applyPlan } from '@slicerx/settings'
const from = { printer: 'bambu_x1c', nozzleDiameter: 0.4, filament: 'pla' }
const to = { printer: 'bambu_x1c', nozzleDiameter: 0.4, filament: 'petg' }
const plan = planSettings(from, to, config, {
intent: { goals: [{ id: 'strength' }, { id: 'speed' }] },
calibrations: [{ id: 'pressure_advance', values: { value: 0.045 }, filament: 'petg' }],
})
plan.changes // key, before, after, reason, sources, origin, klass, approval
plan.warnings // nozzle too small, printer not suited to the material, drying
plan.blockers // an abrasive material on a soft nozzle: changes is empty
plan.questions // things to ask before applying
const updated = applyPlan(config, plan)use sx_settings::plan_json;
let plan = plan_json(r#"{
"from": { "printer": "bambu_x1c", "nozzleDiameter": 0.4, "filament": "pla" },
"to": { "printer": "bambu_x1c", "nozzleDiameter": 0.4, "filament": "petg" },
"base": { "layer_height": 0.2, "nozzle_temperature": [220, 220] },
"options": { "intent": { "goals": [{ "id": "strength" }] } }
}"#)?; // the same JSON as the TypeScript SettingsPlanThe Rust crate also has plan_settings and apply_plan for typed use, and apply_plan_json, validate_json, apply_easy_json, resolve_auto_json and catalog_json for callers that only pass JSON. Rust and TypeScript are tested against the same plans.
Ids are knowledge ids (petg, bambu_x1c). The plan is built in this order: the profile for the target (target), or the printer's baseline process; the filament's starting values and the printer's facts, except keys the target's printer specific profile tuned (tuned); stored calibration results; the merged goals; clamps; and a diff against the current values.
Each change has an origin (printer, filament, nozzle, intent or calibration) and a class from the settings catalog:
edit: may change in a plate override.guarded: always shown.approvalisaskwhen the value lands outside the filament's range. A value past a printer limit is not planned; it appears inrefused.read: shown but never written.applyPlanskips these unless you passincludeRead.
Goals come from knowledge/intents (strength, speed, detail, surface_finish, vase, watertight, flexibility and more; listGoals() gives the ids and levels). When goals conflict, core changes beat supporting ones, stated goals beat inferred ones, and the pair rules decide who keeps which key. What was given up is in tellUser. Every value moved to fit a limit is in clamps.
Keep the reference in sync
The reference is generated from schema.json. After the schema changes, run pnpm gen:reference, which runs node scripts/gen-reference.mjs.