OPENLAB documentation

OPENLAB is a static, client-side open STEM resource ecosystem: a structured project database, a search index, a cost-down engine, an inventory matcher and a local community layer. This page explains exactly how each part works, what the data means, and where it stops.

Everything runs in your browser from plain HTML, CSS and ES modules. There is no server, no account and no analytics. The catalogue currently holds resources built from catalogue components; both numbers are read from the data files at page load.

Data model

Each resource is a record in js/resources.js with these fields. The shape is deliberately close to a repository: it has a README, a bill of materials, code, CAD, a version history and issues.

fieldtypenotes
idslugURL key: resource/?id=slug
title, descriptionstringdescription is 2–4 sentences
difficultyBeginner · Intermediate · Advanced
domainsstring[]one or more of the eight subjects
ageMinnumbershown as “13+”; the age filter keeps resources with ageMin ≤ the chosen age
typehardware · software · mixed
requiresstring[]microcontroller, computer, soldering, mains, sharp, heat, chemicals — used by the “exclude” filters
components{id, qty, core, note}[]id references the catalogue; core marks components the project cannot work without
cost, coreCostnumber (computed)Σ qty × unit cost; never typed by hand
tools, stepsstring[]steps ≥ 6, written as real instructions
code{name, lang, filename, content}[]runnable snippets: Arduino C++, Python, JavaScript/HTML
cad{file, kind, description}[]real files in cad/: OpenSCAD source and SVG cut/print templates
safety{hazard, mitigation}[]specific to the build, not generic
accessibility{lowVision, motor, hearing, textOnly}what adaptations exist; “has adaptations” filter
licensestringCC BY-SA 4.0 for write-ups and CAD, MIT for code-heavy resources
versions{version, date, message, author}[]≥ 2 entries; a short hash is derived for display
tagsstring[]indexed by search

Component catalogue

Components live in js/components.js. Each has an id, a name, a category, a unit cost, synonyms (used by inventory matching and search), and an ordered list of alternatives. An alternative carries the id of another catalogue component, a numeric impact from 0 (identical) to 1 (project no longer works), a plain-language impactText describing what changes, and an availability note. Items flagged salvage cost ₹0 and are things you can typically find: an old CD, a phone camera, a cardboard box, scrap wire. Items flagged assumedOwned (your phone, a browser, a school computer) are treated as available by default.

Prices

Unit costs are indicative Indian street prices in INR for 2026, rounded to what a student would actually pay at a hobby-electronics shop, stationery shop, grocery or online marketplace (an Uno clone ₹450, an SG90 servo ₹110, an LDR ₹8, a 1000 lines/mm grating film ₹600, a 3D-print-service body ₹1,050). Resistors and LEDs are priced per piece even though shops sell them in packs of 10; a resistor assortment is also listed so the inventory matcher can treat a kit as covering every value. Prices vary by city and month; if a listed price is wrong, open an issue on the resource.

Licensing

Resource write-ups, instructions and CAD files are published under CC BY-SA 4.0 unless a resource says otherwise: you may copy, adapt and redistribute them, including commercially, as long as you credit OPENLAB and share adaptations under the same license. Code snippets in resources marked MIT are under the MIT license. Contributions you submit are offered under the license you select in the form; forks inherit the parent's license because CC BY-SA requires it. The OPENLAB site code itself (search, cost-down, inventory, store) is MIT.

The index is built in the browser at page load from every resource's title, tags, domains, component names and synonyms, description and steps. Text is lower-cased, split on non-alphanumerics and stop-words are removed. Each term is stored with the weight of the best field it appears in: title 6, tags and domains 3, components 2.5, description 1, steps 0.4.

For a query, each token scores against a document by exact match (full weight), prefix match (70 %), edit distance 1 for tokens of four or more letters (50 %) or edit distance 2 for seven or more letters (30 %). A document that matches every query token gets a 1.5× boost. Filters (subject, age, difficulty, listed-cost ceiling, required components, type, adaptations, exclusions) are applied after scoring; sort options re-order by cost, difficulty, local rating or last update. The full query state is written to the URL so any search is shareable.

Cost-down algorithm

Input: a resource and a budget B. Output: a substitution report.

  1. Compute the original total from the bill of materials.
  2. Sort lines by subtotal, most expensive first. For each line while total > B: find the cheapest alternative whose impact keeps the core function. For core components that means impact ≤ 0.6; for optional components any alternative is allowed. Alternatives chain one level (X → Y → Z, impacts added) so a grating film can become a CD via the catalogue. Apply the substitution and record the saving and impact text.
  3. If still over budget, drop optional components entirely, most expensive first, recording each as “dropped”.
  4. Report original and final totals, savings in ₹ and %, every original → replacement line, the aggregated impact texts, and whether B was met. If not, report the shortfall and list the closest projects that do fit B.

Worked example: the DIY spectrometer lists a 3D-printed body (₹1,050), a USB webcam (₹950) and grating film (₹600) among ₹2,800 of parts. At B = ₹300 the engine swaps the body for a cardboard build (₹40), the webcam for your phone camera (₹0) and the film for a CD segment (₹0), stopping at ₹240 without touching the razor blades, tape, black paper or the optional CFL calibration lamp. The report says what you lose: about 5 nm resolution instead of 1 nm, hand alignment instead of live capture, and some light leaks to tape over.

Global mode runs the same routine for every resource and ranks them: projects that fit with fewer compromises first (lower aggregate impact), then cheaper; projects that still do not fit are ordered by shortfall. The threshold 0.6 and the impact scores are editorial judgements recorded in the catalogue, not measurements.

Inventory scoring

The inventory text is split on commas, semicolons, new lines and the word “and”. Each fragment is parsed for a leading or trailing quantity (“2 LEDs”, “ldr x2”, “resistor (3)”) and then resolved against the catalogue: exact synonym, singularised synonym, then a token-subset match that prefers the shortest matching synonym. Unmatched fragments are shown as “not in the catalogue” and ignored.

Owning a component also satisfies any component it is listed as an alternative of with impact ≤ 0.6 (a Nano covers an Uno requirement), a resistor kit covers every resistor value, an Arduino/ESP board covers the USB cable it ships with, assumedOwned devices are always available, and if the “household items” box is ticked a fixed list of everyday materials (tape, string, jars, bottles, cardboard, salt…) is treated as owned. Every resource is then scored by core coverage = owned core lines ÷ required core lines. 100 % is buildable now; one or two missing core lines is nearly buildable, with the cost of the missing items. “What to buy next” counts, for each missing component across all non-buildable projects, how many projects it would complete on its own and how many it helps, and ranks by that.

Contribution guidelines

  • Submit a project only if you have built it. The form requires a 2–4 sentence description, at least one catalogue component, at least six steps and at least one specific hazard with its mitigation. Costs are computed from the catalogue; if a part is not in it, name it in the tools or steps and a moderator will add it.
  • Fork when you adapted an existing project — cheaper parts, a different age group, an accessibility variant. Say what you changed and why; the fork is linked from the parent's Adaptations tab.
  • Propose an improvement for corrections to an existing resource: each change is stored as a before/after diff on a named field with your reason.
  • Report an issue for wrong prices, unclear steps, safety concerns, code that does not compile, unavailable parts or accessibility gaps. Issues appear on the resource's Issues tab immediately.
  • Rate once per browser per resource; a short review helps more than the stars.
  • Write for a student reading alone: name the exact pin, the exact quantity, the exact hazard. Do not link to videos as a substitute for steps.

Moderation

Every contribution, fork and improvement starts as pending; every issue starts open. The moderation page lists them with approve / needs-changes / reject (or close / invalid / reopen for issues), an optional note shown back to the contributor, and an append-only log of every action. In this build the queue is local: you moderate what you submitted, in the same browser. A hosted deployment would place the same queue behind authentication, publish approved contributions into the catalogue as new resources or new versions, and expose the log publicly. The data structure does not need to change for that.

Local storage

All state — theme, ratings, issues, contributions, forks, improvements, activity, the moderation log, your inventory text and last budget — is one JSON object under the localStorage key openlab:v1. Every read and write is wrapped in try/catch; if storage is unavailable the site keeps working for the session in memory. The moderation page can export the object as a file or clear it.

Accessibility

  • Semantic landmarks on every page, a skip link, headings in order, real buttons and links.
  • Full keyboard operation: tabs use the ARIA tabs pattern with arrow keys, the star rating is a radio group with arrow keys, filters are native form controls, and the mobile menu is a button with aria-expanded.
  • Dynamic regions (results, cost-down output, inventory output, status lines) are aria-live; toasts are role=status.
  • Light and dark themes both meet 4.5:1 for text; colour is never the only signal (chips carry text, progress bars carry numbers, statuses are words).
  • Typography is in rem; layouts reflow to 375 px and survive 200 % zoom; prefers-reduced-motion disables transitions.
  • Every resource records adaptations for low vision, motor and hearing needs plus a text-only description of the result, and two resources (the Braille board and the tactile graph kit) exist specifically for blind students.

Limitations

  • Prices are indicative and will drift; they are not fetched from any shop.
  • Impact scores and the 0.6 core threshold are editorial, not measured. The engine cannot know that a substitution which is fine for one classroom is unacceptable for another.
  • Alternatives are chained only one level deep, and the engine substitutes greedily by line cost; it does not search for the globally optimal combination.
  • Inventory matching is by synonym, not by specification: “a servo” matches an SG90 even if yours is a larger one, and it cannot tell a 5 V from a 3.3 V module.
  • The community layer is local to one browser. Ratings are your own rating; there is no aggregate across users, and the activity feed only shows what happened in this browser.
  • CAD previews render SVGs inline and show OpenSCAD source; STL rendering is not done in the browser.
  • Code snippets are written to compile against the named libraries but are not run in CI here; report an issue if one fails.