Tenon
Tenon designs flat-pack parts and lays them out on the board you are actually going to cut.
You do not draw anything. You pick a product — a box, a cabinet, a tray, a pegboard panel — and turn its parameters. Tenon generates the parts, cuts the joinery into them, and nests every part of every item onto your stock, redrawing as you type. When it looks right, you either export a CAM-ready bundle of SVGs or send the job straight to MapleCAM to cut.

What it is for
A flat-pack design is a set of parts that fit together with cut joinery — finger joints, half-laps, tabs into slots — so a sheet of plywood becomes a box without fasteners. Getting that right by hand is fiddly: the joints have to interlock, the slots have to allow for the cutter's kerf, and the parts have to fit the board you own. Tenon does that arithmetic.
It is deliberately narrow. It knows about parts, joints, and sheets; it does not generate toolpaths, drive machines, or write G-code. That is MapleCAM's job, and the two hand off to each other.
What a design contains
One design is a cut list:
- Shared stock — one board, one material, one cutter. Every item is cut from the same setup, so the stock lives once at the design level rather than being repeated per item.
- Line items — each a product, its own parameters, and a quantity.
Everything on the list nests together onto the shared board. Change the board thickness and every item's joinery follows, because thickness is what finger joints are cut from.
Where to start
- Installation — get it running.
- Your First Design — a box, start to cut file.
- The Cut List — how stock and items relate.
Tenon is in development. What is documented here is what works today; anything still landing says so on the page.
Installation
Tenon is a desktop application. It runs on Windows, macOS and Linux, and it needs Java 21 or later.
Get Java
Any JDK distribution works — your package manager, your OS vendor, or a build from openjdk.org. Check what you have:
java -version
If that reports 21 or higher, you are ready.
Download and run
Download the JAR for your platform from maplecam.ca/downloads and run it from the directory you saved it in:
java -jar tenon-alpha-<platform>.jar
On Windows, double-clicking the JAR also works once Java is installed.
Each JAR carries the JavaFX native libraries for its own platform, so take the one that matches your operating system and architecture — they are not interchangeable.
There is no server to start
Tenon is split into an application and a local server, the same way MapleCAM is, but you never launch the server yourself. On startup the app either attaches to one already answering on its API port or starts one inside its own process and stops it again on exit.
This matters for one reason: the same design you are editing is reachable over
an HTTP API, so a script or an AI agent can drive it while you watch. If you
want to point the app at a server running elsewhere, set TENON_API_URL before
launching.
Cutting needs MapleCAM
Tenon produces parts and sheets. Turning those into toolpaths and G-code is MapleCAM's job. You do not need it installed to design — export writes plain SVGs that any CAM package can read — but the MapleCAM tab and the direct send only light up when MapleCAM is running. See Sending to MapleCAM.
Your First Design
This walks a box from an empty window to a file you can cut. It takes a couple of minutes and nothing here is destructive — a design is just a text file.
1. Set the stock
The Stock tab describes the board every item will be cut from. Start with the three that matter most:
- Thickness — the actual thickness of your sheet, measured. Not the nominal figure printed on it: 6 mm ply is rarely 6 mm, and every finger joint in the design is cut to this number.
- Board width and Board length — the sheet you are going to put on the machine.
- Cutter diameter — the bit you will cut with. Slots are widened so a round cutter can actually enter them.
Everything else can wait. See Shared Stock for the rest.
2. Add an item
On the Items tab, choose a product — start with Project Box, the glued finger-jointed box — and add it. The form beneath is built from that product's own parameters, so each product shows only what applies to it.
Set the outside dimensions (L, W, H). The preview redraws as you type:
parts appear, joints interlock, and the sheet fills up.
Set a quantity if you want more than one. Quantity is per item, so a cut list of three boxes and one tray is four line items' worth of parts on one board.
3. Read the preview
The preview on the right is the actual sheet. Underneath it, the status line reports what the nester made of the job — how many parts, how many pieces, and whether they all fit. If the job needs more than one board you will see more than one sheet.
If something does not fit, the fix is usually the board, not the design: a longer sheet, or a smaller box.
4. Save it
File → Save As… writes a .tenon file. It is YAML — readable, diffable, and
safe to keep in version control alongside the rest of a project.
5. Cut it
Two ways out, covered in their own pages:
- Export job… writes a folder of CAM-ready SVGs plus a setup sheet. Any CAM package can take it from there. See Exporting a Job.
- The MapleCAM tab sends the job to MapleCAM directly, with your tools and machines already chosen. See Sending to MapleCAM.
What to try next
Turn the thickness up by 3 mm and watch every joint in the design change. That is the whole idea: the parts are generated from the parameters, so the design is never out of step with the material.
The Cut List
A Tenon design is not a drawing of one object. It is a cut list: shared stock, plus a list of line items to cut from it.
design
├── stock one board, one material, one cutter — shared by everything
└── items
├── project box L=310 W=210 H=110 × 3
├── divider 3 × 2 spots × 1
└── marker "whatsit.ca" × 2
Why stock is shared
Because you cut a job, not a part. Every item on the list goes onto the same sheet in the same setup, so the board, the material and the cutter belong to the design rather than to any one item.
It also keeps the joinery honest. Finger joints are cut from the material thickness — a 6 mm box and a 9 mm box are different geometry, not the same geometry scaled. With one shared thickness, every item in the design agrees about the material it is made of, and changing it updates all of them at once.
Why items carry quantity
Quantity belongs to the item because the nester needs to place every copy. Three boxes is not one box cut three times: it is fifteen pieces that all have to fit on the board together, and the layout is different from one box's.
The status line under the preview reads out both numbers — parts (distinct shapes) and pieces (how many get cut).
Editing is live
Every change — a parameter, a quantity, an item added or removed — recomputes the parts and re-nests the sheet immediately. There is no generate step and no stale preview: what you are looking at is the job.
The design is the file
A design saves as a .tenon file containing exactly this structure: the stock
block, then the items with their parameters and quantities. Nothing is baked;
opening it rebuilds the parts from the parameters, so a design saved against
6 mm ply can be re-cut in 9 mm by changing one number.
Shared Stock
The Stock tab is the board every item is cut from. These settings apply to the whole design.
Panel and material
Thickness (mm) — the measured thickness of your sheet. This is the single most consequential number in a design: finger joints, slot depths and tab lengths are all cut from it. Measure the actual board. Sheet goods are routinely half a millimetre off nominal, and half a millimetre is the difference between a joint you tap together and one you hammer.
Board width / Board length (mm) — the sheet size the nester lays parts onto. If the job needs more than one, it fills additional sheets.
Material — a label carried through to the export and to MapleCAM, so the setup sheet says what to load.
Solid board edge — how the nester may treat the board's edges: whether it can run parts up to the edge, or must keep clear of it. Use clamp border when the sheet is held down at its edges and the cutter must not reach them.
Keep stock (mm) — margin held back from the board, for the same reason.
Cutting
Cutter diameter (mm) — the bit doing the cutting. A round cutter cannot cut a square internal corner, and it cannot enter a slot narrower than itself, so slots are widened to at least this. Set it to the tool you will actually use; too small a value produces a design your machine cannot cut, and too large loosens every joint.
Fit clearance (mm) — how much slack a joint gets. Zero is a theoretical perfect fit, which in real plywood means a joint you cannot assemble. A few tenths is normal; more for rough material or a machine with backlash.
Joint fit — the named fit preset (e.g. slip fit), which sets how tight interlocking parts are relative to the clearance above.
Tab recess (mm) — how far a plain tab sits below the surface it passes through, so nothing stands proud of a finished face.
Marking and layout
Board marks — whether the sheet carries its identifying marks (panel number, order number, registration scores).
Order no. — free text stamped on the job, so a cut sheet on a bench can be matched to the order it belongs to.
Nest in windows — whether the nester may place small parts inside the waste windows of larger ones. It packs tighter; leave it off if you would rather those cut-outs stayed intact.
Changing stock later
Any of these can change at any time and the whole design follows — that is the point of parameters. The one to be careful with is thickness: it changes every joint in every item, so a design cut successfully in one thickness should be re-checked in the preview after a change rather than sent straight to the machine.
Joinery and Fit
Tenon's products are held together by cut joinery — geometry, not fasteners. This page explains what it generates and which settings move it.
Finger joints
Box corners are finger-jointed: alternating fingers and sockets, each one material-thickness deep, so the two walls interlock and register themselves square. The pitch is a parameter on the products that use it; the depth always comes from the stock thickness.
Tabs and slots
A captured bottom does not sit in a groove — it carries tabs that pass through slots in the walls. That way the floor is located in all three axes by geometry alone, and the box cannot rack.
Plain tabs are recessed slightly below the outer face (Tab recess) so nothing protrudes on a finished surface. Some products hook their tabs instead, so a pin can draw the joint tight.
Pinned versus glued
Two boxes of the same size can be built two ways:
- Glued (Project Box) — the joints go together with adhesive and stay together. Fewer parts, simpler cut.
- Pinned (Pinned Project Box) — the corners carry hooked tenons drawn tight by a separate flat pin, so the box knocks down and reassembles. More parts: each hook needs its pin.
Pick glued for a box that will live assembled, pinned for one that has to ship flat or come apart.
Half-laps
Dividers and trays interlock with half-lap crossings: each board is notched halfway through where it meets another, so the grid assembles flush. This is why a divider's boards do not need any fasteners either.
Kerf, clearance and fit
Three settings decide whether the parts you cut actually go together:
| Setting | What it does |
|---|---|
| Cutter diameter | Slots widened so a round cutter can enter; internal corners cannot be sharper than this |
| Fit clearance | Slack added to mating features so a joint can be assembled |
| Joint fit | The named preset (e.g. slip fit) that sets how tight the interlock is |
The cutter cannot cut a sharp internal corner, so a socket cut with a 3.175 mm bit has 1.6 mm radii in its corners, and a square finger will not seat fully into it. Products handle this in their geometry; what you control is telling Tenon the truth about the cutter.
If joints are too tight, raise fit clearance a tenth or two. If they are sloppy, lower it — but check the cutter diameter first, since an overstated cutter widens every slot.
Test before you commit
Cut one corner in the real material before cutting a whole job. Fit is the one thing the preview cannot tell you: it depends on your machine, your bit and your plywood, and a tenth of a millimetre either way is the difference between a press fit and a gap.
Nesting and Sizing
Every part of every item is laid out on the shared board automatically, and re-laid out on every change. That layout is the sheet you cut.
What the nester does
It takes the full set of pieces — every part of every item, times its quantity — and places them on the board, respecting the margins the stock settings impose: the kept-back edge stock, and whether parts may run to a clamped edge.
If everything does not fit on one board, it fills another. A job can span as many sheets as it needs, and the preview shows each.
Reading the sizing line
Under the preview, the status line reports the job:
- parts — distinct shapes in the design.
- pieces — how many actually get cut, quantity included.
A three-box design has the same parts as a one-box design and three times the pieces.
If some pieces could not be placed, that is reported too — the job as specified does not fit the board you gave it.
When it does not fit
The nester will not silently shrink anything. Your options, roughly in order of how often they are the right answer:
- Use a bigger board. Most often the design is fine and the sheet is small.
- Split the job. Cut it as two designs, or drop a quantity.
- Turn on Nest in windows. Small parts get placed inside the waste windows of larger ones. Tighter, at the cost of those cut-outs.
- Reduce keep-stock margin. Only if your workholding genuinely allows it.
Sheet layout is not yours to place
Placement is automatic and not hand-editable in the general case — it is recomputed on every parameter change, so any manual arrangement would be discarded the moment you typed a number. Design intent lives in the parameters; the layout is derived.
Grain
Products declare grain direction where it matters structurally. The nester honours those constraints when placing, so a part that must run along the grain is not rotated to save space.
The Catalogue
Every product is a generator: parameters in, parts out. Adding one to a design gives you its own parameter form, and its geometry is rebuilt from those parameters every time they change.
| Product | id | What it is |
|---|---|---|
| Project Box | project_box | Glued finger-jointed box with a captured bottom |
| Pinned Project Box | pinned_box | The same box, knock-down: hooked tenons drawn tight by flat pins |
| Produce Box | produce_box | The glued box with every face turned into a honeycomb grille — a ventilated crate |
| Cabinet | cabinet | A single column of openings — drawer, door, open bay or display — in a finger-jointed carcass with a captured back |
| Drawer | drawer | A lean finger-jointed box sized to a cabinet opening |
| Divider | divider | Egg-crate grid of half-lapped boards, sized to a box's interior |
| Tray | tray | A floor with border walls and per-bay half-lap dividers |
| Skadis Panel | skadis_panel | Pegboard panel cut to the IKEA Skadis hole pattern |
| Plate | plate | A bare rectangular blank for engraving — nameplate, award, label |
| Marker | marker | An engrave-only branding tile: artwork plus a line of text, nothing cut |
The id is what appears in a saved .tenon file and in the HTTP API. The
title is what the app shows.
Sizes are external
Where a product takes L, W and H, those are outside dimensions. The
interior is whatever is left after the walls, and the app reports it back to you
— a box with 310 mm outside length in 9 mm ply has a 292 mm interior, and the
readouts say so rather than making you work it out.
This is the right way round for the usual question, which is "will it fit on that shelf", not "how thick are its walls".
Parameters are validated
A product refuses parameters it cannot build — a box too short for its own handle, a lidded box too thin for the lid notch. The message says which dimension is fighting which, and what to change. That is a contract failure, not a bug: it is the product telling you the object cannot exist in that material.
Adding products
Products are discovered from the engine, not hard-coded into the UI. A new product appears in the picker with its own form the moment the engine offers it — no UI change, and no update to this guide's mechanics.
Boxes
Three boxes, same lineage: a finger-jointed carcass around a captured bottom, with a stacking crown on the end walls so one nests onto the next.
Project Box (project_box)
The glued box. Four walls box-jointed at the corners, a bottom captured on tabs through the walls, an optional handle in the end walls, and an optional lid.
Choose it when the box will be assembled once and stay that way. It has the fewest parts and the simplest cut.
Key parameters: L, W, H (external), handle on/off, lid style, finger
pitch.
Pinned Project Box (pinned_box)
The same box, knock-down. Each corner carries a hooked tenon plus a plain registration tenon, and a separate flat hook pin scissors the hook to draw the joint tight. The captured bottom hooks the same way.
Choose it when the box has to ship flat or come apart. The cost is parts: one pin per hook — four corners plus the bottom's hooks — and a slightly busier sheet.
Key parameters: as the Project Box, plus hook angle, the ramp angle the pin rides. Shallower self-locks harder but makes a taller hook; the default is a sensible middle.
A caution worth stating: on a very shallow box the hook has little room to ramp into, and Tenon shortens it to fit rather than letting the geometry cross itself. A box under about four times the material thickness in height will hold less well than a taller one.
Produce Box (produce_box)
The glued box with every face turned into a honeycomb grille, and no lid — a ventilated crate. Same carcass, stacking crown, handle and captured bottom; the vents are the only addition.
Choose it for anything that needs airflow. Expect a longer cut: the grille is a lot of internal geometry.
Lids
Where a box offers a lid, the options are none, cover slots (the walls are notched to receive a sliding cover) or a full cover.
A lid consumes the top of each wall for its notch, which is why a wall too short or too thick for both the notch and its corner tenon is rejected outright rather than built wrong.
Stacking
The end walls carry a crown: a bump on top, a congruent indent underneath. A stacked box self-centres on the one below, and the indent exposes the captured bottom's edge as a lip for the bump to seat against. Boxes of the same footprint stack whether they are glued or pinned.
Cabinets and Drawers
Cabinet (cabinet)
A single column of openings in a finger-jointed carcass with a captured back. Each opening is independently a drawer, a door, an open bay or a display, so one parametric product covers what would otherwise be a shelf of separate designs — workshop cabinet, kitchen cabinet, wall cabinet, open shelving.
You describe the column: the carcass size, then what each opening is. The carcass, dividers and back are generated to suit.
Because it is one column, a wider run is several cabinets side by side rather than one cabinet with two columns. That is a deliberate limit — it keeps the joinery honest and the nesting predictable.
Drawer (drawer)
A lean finger-jointed box sized to a cabinet opening: four walls box-jointed around a captured, tabbed bottom, and none of the box's extras — no handle, no stacking crown, no lid.
It is available as its own product, so you can cut a replacement drawer for an existing cabinet without regenerating the cabinet.
Sizing a drawer to an opening
A drawer has to be smaller than the hole it slides into, by enough for the runners or the clearance you intend. Tenon does not assume a runner system, so the gap is yours to specify: size the drawer to the opening minus your clearance, and cut one before committing to a set.
Inserts
Two products that go inside something else.
Divider (divider)
An egg-crate: a grid of boards that slot together with half-lap cross-laps, sized to a box's internal dimensions.
You give it the grid — X by Y spots — and it works out the boards. An X×Y
grid needs X-1 cross boards and Y-1 long boards, each notched halfway
through where they cross, so the assembly is rigid without glue or fasteners.
The size to give it is the box's interior, which the box's own readouts tell you. Design the box first, read its internal dimensions, then size the divider to them.
Tray (tray)
A flat floor, four border walls that capture the contents, and a configurable per-bay layout of half-lap dividers slotted into the floor.
Unlike the divider, the tray is glued, which keeps its underside flat. That matters: a tray with nothing protruding underneath will seat on top of a box divider without needing clearance cut for it, so trays and dividers stack in the same box.
Choose a tray when the compartments need a floor — small parts, tools, anything that would otherwise fall through to the bottom of the box. Choose a divider when the box's own floor is the floor.
Sizing inserts
Both are sized to fit something, and both are cut from the same shared stock as the thing they go into. Two consequences worth remembering:
- Changing the design's thickness changes the insert's boards as well as the box's walls, so the fit is maintained.
- Fit clearance applies here too. An insert that drops into a box wants a little more slack than a joint that is meant to be tight.
Panels and Plates
Three products that are a single piece rather than an assembly.
Skadis Panel (skadis_panel)
A pegboard panel cut to the IKEA Skadis hole pattern, so standard Skadis accessories clip into it.
The field is a grid of vertical 5 × 15 mm obround slots on a 40 mm pitch, with alternating columns staggered half a pitch. Give it a panel size and it fills the field.
Use it to make a Skadis-compatible panel in a size IKEA does not sell, or in material that matches the rest of your shop.
Plate (plate)
A bare rectangular blank — a nameplate, an award plate, a label — sized by its width and height and the shared stock thickness, and nothing else.
The plate deliberately has no marks of its own. Everything on it is applied as a decal: a logo, a rule, lines of text. That keeps one product covering every plate you might cut instead of growing a parameter per kind of marking.
Marker (marker)
An engrave-only branding tile: a rectangular panel carrying centred artwork scaled to fit and a line of text scored beneath it — and nothing cut.
The distinction from a plate matters. A plate is cut out of the sheet; a marker is only engraved onto it. Use a marker to brand a surface in place — the inside of a box lid, a corner of a panel — where cutting it free would be wrong.
When to use these instead of decals
A plate or a marker is a line item on the cut list, so it nests as its own piece and can carry a quantity. A decal is applied to another part. If you want ten identical badges, that is a plate with quantity ten. If you want your mark on the bottom of every box, that is a decal on the box.
Decals and Components
A decal puts an artifact on a part: a logo, a QR code, a line of text, a maker's mark. Products carry no branding of their own — it is all applied this way, so any mark can go on any part of any product.
Kinds
| Kind | What it places |
|---|---|
text | Engraved text — single-stroke, using a built-in engraving face |
filledtext | Filled text from a TTF/OTF font file |
svg | Artwork from an SVG file, or inline SVG markup |
qr | A QR code from a URL or any text |
datamatrix | A Data Matrix code, same idea in a smaller footprint |
rect | A solid filled rectangle, sized to the decal's box |
Engraved (text) and filled (filledtext) text are genuinely different
operations, not two styles of one. Single-stroke text is scored — the tool
follows the letterform once, quickly. Filled text is cleared out, so it reads at
a distance and takes considerably longer to cut.
Placement
A decal is placed on a named part, at a position in that part's own frame, sized to fit a box you give it — width and height, in millimetres. It can be turned in quarter turns.
Sizing is fit-within, not stretch: artwork keeps its proportions inside the box you specify.
Where the files live
An SVG decal's artwork and a filled-text decal's font are referenced by path, and a path is resolved relative to the design file's own directory. Keep artwork beside the design and it travels with it; use an absolute path and the design only opens on the machine that has that file.
Cut blocks
Each decal carries a block token — logo, qr, and so on. That token follows
the geometry into the export and into MapleCAM, where it becomes the grouping
that operations select on. It is what lets a whole job say "engrave every logo
with this tool" without naming parts one at a time.
Components
The Components menu handles reuse:
- Save selection as component… stores what you have selected so it can be used again.
- Add component… brings one into the current design.
Use it for the marks you apply on everything — a maker's mark with your logo, your URL as a QR, and your name in text, positioned the way you like it — so each new design is one insertion rather than three placements.
Saving and Opening
The design file
File → Save and Save As… write a .tenon file. Older saves use
.tenon.yaml; both open.
The format is YAML, and it is meant to be read:
stock:
T: 6.35
SHEET_W: 1150.0
SHEET_L: 590.0
MATERIAL: Baltic birch ply
TOOL: 3.2
CLR: 0.2
items:
- product: project_box
quantity: 3
params:
L: 310.0
W: 210.0
H: 110.0
LID: slots
HANDLE: 'yes'
Parameters, not geometry. Opening the file rebuilds every part from these
numbers, which is why a design survives a change of material: edit T, and the
joinery is regenerated to suit.
It also means designs diff usefully. A commit that changes a box's height shows as one changed line, and two versions of a job can be compared without opening either.
Recent files
The app keeps a recent-files list, so the design you were working on last is one click away. That list is the only thing Tenon stores locally on your behalf — everything else about a design is in the design file.
Where files are read and written
Saving, opening and exporting are done by Tenon's local server, not by the window. You choose the path in the file dialog and the server does the writing.
This is invisible in normal use — the app and its server are the same machine.
It only matters if you point TENON_API_URL at a server on another host, in
which case the paths you choose are interpreted on that machine, and
save/open/export will not do what you expect. Running against a remote server is
not a supported setup for that reason.
Keeping designs with a project
A design references its artwork and fonts by path, resolved against the design's
own directory. Keeping the .tenon file, its SVGs and its fonts in one folder
makes the whole job portable — copy the folder, and it opens anywhere.
Exporting a Job
Export job… writes the CAM-ready bundle into a folder you choose. This is the route that does not need MapleCAM: the output is plain SVG, which any CAM package can read.
What lands in the folder
For each panel in the job:
panel-<n>-cut.svg— the cut contours.panel-<n>-engrave.svg— the engraved marks.panel-<n>-combined.svg— both together, for looking at.
Plus one maplecam-setup.txt — the setup sheet, telling whoever is running the
machine which stock to load and how to machine each SVG.
The combined file is the one to open when you want to check the job by eye. Cut from the separate files.
Why cut and engrave are separate files
Because they are different operations with different tools, and often different machines: a router cuts the outlines while a laser does the engraving, or a single machine does both in two setups with a tool change between.
Keeping them apart means each file maps to one operation with one tool, and nothing has to be filtered by layer or colour downstream.
Multiple panels
A job that needs more than one board exports one pair of files per panel, numbered. Cut them in order; the setup sheet lists what each one needs.
The setup sheet
Read it before cutting. It names the material and thickness the design was built for — a job cut in the wrong thickness will have joints that do not fit, and the sheet is the check against that. It also carries any warnings the job generated, such as holding-tab caveats.
Headless export
The same bundle can be produced without opening the window:
tenon --export <design.tenon> --out <dir>
Useful for regenerating a job in a script, or rebuilding every design in a
folder after changing a shared component. Add --3d for the 3D output.
Sending to MapleCAM
The MapleCAM tab hands the job to MapleCAM directly: the parts arrive on stock as a project, with operations already set up from the choices you make here. No exporting, no re-importing.
MapleCAM must be running. While it is not reachable the tab says so and keeps checking, so starting MapleCAM after Tenon recovers on its own within a few seconds.
Choosing tools
The tab lists the tools from MapleCAM's own library — the same presets you maintain there, not a second copy. Reload re-reads them if you have just added one.
Pick two: the engrave tool and the cut tool. They can be on different machines, which is the point of the machine pickers beside them: engrave on the laser, cut on the router, in one job.
Options
Leave holding tabs — small uncut bridges that hold each part to the sheet so it cannot come loose and be thrown while the cut finishes. Set the tab size in millimetres beside the checkbox. Leave this on for anything cut on a router.
Score cut outlines (verify pass) — traces the cut outlines with the engrave tool before cutting them. A cheap dry run: you see exactly where the parts will land on the board and can confirm the stock is positioned correctly before any material is removed.
Cut filled shapes (outline only) — cuts around filled artwork rather than clearing it out. Faster, and appropriate when the "fill" is meant to be a cut-out rather than an engraved area.
What arrives in MapleCAM
A project per panel, containing the panel's geometry as parts on stock, with operations generated for the tools you chose: laser contours for a laser cut, spindle contours for a router, engrave or fill operations for the marks, each selecting on the decal blocks the design carries.
From there it is an ordinary MapleCAM project. Generate the toolpaths, check the simulation for overcut, and export G-code.
If a send is rejected
MapleCAM validates what it is given and refuses a job it cannot cut safely. The messages are specific — a laser whose lens cannot focus as deep as the cut asks, a tool too short for the material. Fix it on the MapleCAM side (a different tool or lens) or on the Tenon side (thinner stock), and send again.
Nothing is lost when a send is rejected: the design is untouched, and the validation happens before any toolpath is generated.
Files and Locations
Your files
| What | Where |
|---|---|
| Designs | Wherever you save them — .tenon (older saves: .tenon.yaml) |
| Exported jobs | The folder you pick in Export job… |
| Decal artwork and fonts | Referenced by path, resolved against the design's own directory |
Tenon's files
| What | Where |
|---|---|
| Recent-files list | $XDG_CONFIG_HOME/tenon/recent.txt, or ~/.config/tenon/recent.txt |
That list is the only thing Tenon keeps on your behalf. There is no library, no preferences database and no cache to go stale: a design carries everything about itself, and the tools come from MapleCAM's library rather than a second copy here.
Exported bundle
<chosen folder>/
├── panel-1-cut.svg
├── panel-1-engrave.svg
├── panel-1-combined.svg both layers, for checking by eye
├── panel-2-cut.svg (only if the job needs a second board)
├── panel-2-engrave.svg
├── panel-2-combined.svg
└── maplecam-setup.txt
The local API
| What | Value |
|---|---|
| Default API port | 8788 |
| Override | TENON_API_URL |
The app self-hosts a server on that port — attaching to one already there, else starting one it stops on exit. It is a first-class HTTP API, so the design open in front of you can also be driven by a script or an agent.
Setting TENON_API_URL attaches to an external server instead, and that server
is never stopped by the app. Note that file operations run on the server's
machine, so pointing this at another host breaks save, open and export — see
Saving and Opening.
MapleCAM
| What | Where |
|---|---|
| Tool and machine libraries | MapleCAM's own, under ~/.maplecam/ |
Tenon reads MapleCAM's library over its API when the MapleCAM tab is open. It never copies or caches it, so a preset you add in MapleCAM is available here as soon as you press Reload.
Command Line
Launching
java -jar tenon-alpha-<platform>.jar [design.tenon]
A file argument opens that design on launch, which is also what the desktop
launcher uses when you open a .tenon file from your file manager.
Headless export
Produce a job's CAM bundle without opening the window:
tenon --export <design.tenon> --out <dir> [--3d]
Both flags are required together. --3d additionally writes the 3D output.
The bundle is identical to what Export job… writes — per-panel cut and
engrave SVGs plus maplecam-setup.txt — so this is the way to regenerate jobs
in a script: after changing a shared component, or to rebuild a folder of
designs against new stock.
Environment
| Variable | Effect |
|---|---|
TENON_API_URL | Attach to an external tenon-server instead of self-hosting. The app never stops a server it attached to. |
XDG_CONFIG_HOME | Where the recent-files list lives; defaults to ~/.config. |
Driving the API directly
The app self-hosts its server on port 8788, and that API is the same one the UI uses — there is no private back channel. A design open in the window can be listed, edited and exported over HTTP while you watch it update.
That makes scripted and agent-driven use a first-class path rather than an
afterthought: anything the interface can do, a curl can do.
FAQ
What Java version do I need? Java 21 or later, any distribution.
Do I need MapleCAM? Only to cut through it. Designing and exporting need nothing else — the export is plain SVG. The MapleCAM tab and the direct send need MapleCAM running.
Do I need an internet connection? No. Tenon runs entirely on your machine and sends nothing anywhere.
My joints are too tight to assemble. Raise Fit clearance a tenth or two. Before that, check Thickness against a caliper and Cutter diameter against the bit you actually used — an overstated cutter widens every slot, and an understated one makes every joint tight.
My joints are sloppy. Lower fit clearance. If they are sloppy in one axis only, the thickness is probably wrong: measure the sheet rather than trusting the label.
The parts do not fit on my board. Give it a bigger board, cut the job in two, or turn on Nest in windows to let small parts sit inside larger parts' cut-outs. See Nesting and Sizing.
Can I move parts around on the sheet myself? Placement is recomputed on every change, so a manual arrangement would not survive your next keystroke. Change the board or the parameters instead.
A product refuses my dimensions. That is the product saying the object cannot be built in that material — a box too short for its own handle, a lidded wall too thin for both the lid notch and its corner tenon. The message names what is fighting what.
Why is my pinned box's hook so short? On a shallow wall there is little room for the hook's ramp, and Tenon shortens it to keep the outline cuttable rather than letting the geometry cross itself. A box under roughly four times the material thickness in height will hold less firmly; use a taller box or the glued Project Box.
Where did my decal's logo go? Artwork paths resolve against the design file's directory. If the design moved and the artwork did not, the reference is dangling — keep them in one folder.
Can I use it with a laser? Yes. Choose laser tools in the MapleCAM tab; the cut becomes laser contours rather than spindle contours. Mind the lens: a laser cannot focus deeper than roughly its focal length divided by 1.5, so a short-focus diode lens will refuse thick stock.
Is it free? Yes. No account, no subscription. If it is useful to you, donations are welcome at paypal.me/maplecam.
Something is wrong and this page did not cover it. Email info@whatsit.ca with the design file, what you expected, and what happened.