Full grading rubric
Use a shared set of heuristics to score template quality consistently across Astryx usage, icons, CSS, layout, metadata, images, and code quality.Understand the score
Template rubric 1.4 scores seven categories for 100 points. Aim for 100; B (75) is the publication floor, not the target. Each category below lists its weight. Never award points for anything you did not inspect.
| Grade | Score | Meaning |
|---|---|---|
| A | 90-100 | Exemplary. Copy-ready with no known quality problems. |
| B | 75-89 | Good. Minor issues may remain, but the template is usable. |
| C | 60-74 | Needs work before publication. |
| D | 40-59 | Poor. Significant rewrites are needed. |
| F | 0-39 | Failing. The template teaches or produces bad patterns. |
Keep improving while a deduction has a reasonable fix. A score below 100 is fine only when the remaining tradeoff is intentional and recorded. A template is not ready if the copied file fails to build or a required asset is missing, whatever its score.
Version 1.4 counts public integration components as Astryx components and grades assets and imports after the copy. Record the version with every score so results stay comparable.
Astryx component purity: 30 points
Count every JSX opening tag in the copied .tsx source. An Astryx element is a component imported from @astryxdesign/core or from a public component export of the integration package. A raw HTML element is any lowercase intrinsic JSX tag. Count occurrences, not only unique tag names.
Do not count fragments or a PascalCase helper defined in the same file. Inspect that helper and count the raw HTML inside it. For each raw element, decide whether it is necessary because Astryx has no equivalent, or unnecessary because an Astryx component can replace it.
| Raw HTML elements | Points |
|---|---|
| 0 | 30 |
| 1-2, all necessary | 25 |
| 1-2, any unnecessary | 20 |
| 3-5 | 15 |
| 6-10 | 8 |
| 11-20 | 4 |
| 21 or more | 0 |
| Raw HTML use | Astryx replacement |
|---|---|
div for layout | VStack, HStack, Card, Section, or Center |
div for a grid | Grid |
span or p for text | Text |
h1 through h6 | Heading level={N} |
button | Button or IconButton |
a | Link |
In-page nav or aside | LayoutPanel in the start slot |
header or main | LayoutHeader or LayoutContent in Layout |
ul, ol, or li | List and ListItem |
input, textarea, or select | The matching Astryx form control |
table, tr, or td | Table |
hr | Divider |
dialog | Dialog |
details or summary | Collapsible |
- Do not deduct for an
imgwhen no general Astryx image component fits and its source passes the Image handling category. - Do not deduct for a
formthat wrapsFormLayoutto provide native submission semantics. - Do not deduct for
input type="hidden"when it carries native form state.
Icon purity: 15 points
Count raw icon markup in the copied file. astryx docs cli/integrations/building-blocks/templates/build-the-template/template-assets/template-icons shows how to render icons through Astryx instead.
- Count every raw
svg,path,circle,rect,line,polyline,polygon,ellipse, orgused as an icon. - Count an inline SVG component defined in the template.
- Count an icon component rendered directly instead of through
Iconor an Astryx icon prop.
| Raw SVG icon instances | Points |
|---|---|
| 0 | 15 |
| 1-2 | 10 |
| 3-5 | 5 |
| 6 or more | 0 |
Custom CSS: 15 points
Prefer Astryx component props and design tokens. Count individual CSS properties inside stylex.create and inline style objects. Count each className and stylex.props use once. Do not count Astryx props such as gap, padding, variant, size, color, level, columns, contentPadding, or height.
| Custom style declarations | Points |
|---|---|
| 0 | 15 |
| 1-3, all justified because no Astryx alternative exists | 12 |
| 1-3, any unjustified because an Astryx prop exists | 8 |
| 4-10 | 5 |
| 11-20 | 2 |
| 21 or more | 0 |
This category scores styles authored in the copied source. A package stylesheet is graded through its effect on portability and the rendered app, not as a way to hide custom declarations from this count.
Layout and structure: 15 points
Page templates
- Use
LayoutorCenteras the page root. A template whose category starts withShell -usesAppShellbecause global chrome is its purpose. - Outside a
Shell -template, leave global navigation to the host app. Put in-page navigation in aLayoutPaneland page headings inLayoutHeader. - Use
Gridwithcolumns={{minWidth: 280}}for responsive collections. Do not fix the column count or rebuild the grid in raw CSS. - Use
Centerfor centered content instead of custom flexbox workarounds. - Render one page from one source file. Links may be inert examples, but the template does not create nested routes or router integration.
| Page condition | Points |
|---|---|
| Correct root, responsive grids, proper centering, and one page | 15 |
| Valid root with a smaller issue such as fixed columns or multi-page behavior | 8 |
| Wrong root for the category, a raw layout root, or no Astryx root | 0 |
Block templates
- Do not wrap a block in
AppShell. A block renders inside a preview or page container. - Keep the block focused on one pattern or component usage.
- Keep the composition substantial enough to teach the pattern and small enough to adapt. About 20-100 lines is the normal range.
Doc metadata: 10 points
Score field accuracy for 6 points, the description for 3 points, and naming for 1 point. Read the source and doc together. A field that exists but disagrees with the source is not complete.
Fields: 6 points
- Page:
type,name,displayName,description, explicitisReady, and a specificcategorywhen the page is meant for browsing. - Block:
type,name,displayName,description, explicitisReady, positiveaspectRatio, and completecomponentsUsed. - Relationship and preview fields follow
astryx docs cli/integrations/building-blocks/templates/document-the-template/block-template. A value that contradicts that guide is an inaccuracy.
| Field condition | Points |
|---|---|
| All applicable fields are present and accurate | 6 |
| All fields are present with one inaccuracy | 4 |
| One required field is missing | 2 |
| Two or more required fields are missing, or no doc exists | 0 |
Description: 3 points
A strong description covers four slots: the archetype, the job someone does, the structural or behavioral differentiator, and the alternate words people may search. Use at least six distinct content words after removing generic words such as page, screen, app, view, and component names. Describe the reusable shape, not only the sample data.
| Description condition | Points |
|---|---|
| All four slots, 6 or more distinct content words, and clear separation from sibling templates | 3 |
| Names and differentiates the pattern but misses one slot or leaves a synonym implicit | 2 |
| Generic, repeats component names, or describes only the sample data | 1 |
| Missing or restates the name | 0 |
Naming: 1 point
The id follows astryx docs cli/integrations/building-blocks/templates/start-a-template, displayName is readable, and a browsable page has a specific category (astryx docs cli/integrations/building-blocks/templates/document-the-template/page-template). Slug length is guidance, not a scored condition.
| Naming condition | Points |
|---|---|
| Id, display name, and applicable category follow the convention | 1 |
| Any naming or category requirement is missed | 0 |
Image handling: 5 points
Inspect every image reference in the copied file against astryx docs cli/integrations/building-blocks/templates/build-the-template/template-assets/template-images-media.
| Image condition | Points |
|---|---|
| No image is needed, or every image still works after copy and the demo-placeholder behavior is intentional | 5 |
| One optional demo image is missing in preview, or a placeholder service remains | 2 |
| An essential image breaks after copy, uses a package-relative path, or depends on an inaccessible URL | 0 |
Code quality: 10 points
Award 2 points for each condition. Grade the copied file, not only the package source.
| Condition | Points | How to verify |
|---|---|---|
| Correct client boundary | 2 | use client is the first executable statement when hooks, event handlers, or browser APIs require it. A static template does not add it without need. |
| Default export | 2 | The copied file has one default-exported React component. |
| Self-contained imports | 2 | Every import resolves from the copied location through React, a public Astryx path, a public integration-package export, or an app dependency the template explicitly requires. |
| Realistic example data | 2 | Content has realistic names, amounts, dates, lengths, and states instead of lorem ipsum or numbered placeholders. |
| No dead code | 2 | There are no unused imports or variables, commented-out blocks, or helpers that are never called. |