Open edX XBlock development

A guide for teams deciding whether a custom XBlock is the right way to extend an Open edX course, how to build and test it with Tutor, and how to keep it working as named releases change.

On this page

Open edX XBlock development: when a custom block is the right tool

A custom XBlock is justified when a component must run inside course content and track learner progress, and no existing Open edX component can do that job with configuration alone. If a team only needs a link, a static page or a theme change, a block is the wrong tool. Once a block is built, it becomes a code commitment: the team owns its behavior, its tests and its compatibility with every platform release it will run on for as long as learners use it. The work is harder than it looks because an XBlock is not a single-purpose plugin. The Open edX platform is licensed under the GNU Affero General Public License version 3 and is built on Python, JavaScript and Django, and it delivers two core services: Studio (CMS) for authoring and the LMS for learners. A block has to render and behave correctly in both. An author places and configures it in Studio, and a learner interacts with it in the LMS, so a defect in either place is visible to a course team or a student.

Packaging is the next step that surprises teams. Tutor is the official Docker-based Open edX distribution for production and local development, and it builds the images that run the platform. A block that works in a developer's local environment still has to be installed into those Tutor-built images, typically through a Tutor plugin, before it reaches a staging or production environment. Confirm with your delivery team how blocks are versioned, built and promoted between environments, and who approves each image.

The most expensive ongoing obligation is upgrade testing. Open edX states that the latest named release is the only supported release and that it cannot support more than one release at a time. This means a block must be retested against each new named release your organization adopts, not only when your own code changes. Plan for a regression pass that covers authoring in Studio, learner interaction in the LMS, grading and any data the block writes, and record who owns that pass before the first course depends on the block.

Before committing, ask three questions. Does the requirement need to sit inside course structure and learner state, or can it be met by an existing component or an external tool launched from the course? Who in your organization will maintain the block after the build partner hands it over? And how will the block be tested against the next named release, including the frontend changes that release may bring? If the answers are unclear, scope a short design review first so the team can compare a custom block with the alternatives on paper, not after the code exists.

Which Open edX parts an XBlock touches and how the block is built

A custom XBlock sits inside several layers of the Open edX platform at once: the edx-platform codebase, the Python package that defines the block, its front-end assets, and the Tutor build that installs it. Knowing which layer owns which behavior tells a team where to build, where to test and where upgrades are most likely to break the block.

The edx-platform modular monolith

Open edX is a modular monolith built on Python, JavaScript and Django, and it delivers two core services: Studio (CMS) for course authoring and the LMS for learners. A block must work in both, so the team should check how the block loads in each service rather than assuming one runtime. Confirm which Studio and LMS paths your target release exercises before scoping tests.

The Python package that defines the block

The block is a Python package that declares an XBlock class, its fields and its registration with the platform through an entry point. Keep business logic in this package and keep it free of direct edx-platform imports where possible, since those internal imports are what break during upgrades. Confirm the current entry point group name and XBlock API details in the official XBlock and Open edX developer documentation for your target release.

Author and student views

An XBlock exposes separate views for authoring in Studio and for learners in the LMS, and the same block instance can render differently in each context. Studio views typically provide editing forms, while student views render the learner experience and submit responses. Test both views for every change, because a block that renders correctly for learners can still fail in the authoring form.

Fields that store block state

Fields hold the block's settings and learner-independent or learner-specific state, and the platform persists them within the course structure or the learner's state store depending on field scope. Changing a field name or type in a later release can orphan existing course data, so plan a migration path before the first course uses the block. Confirm field scope and persistence rules against the XBlock documentation for your release.

JavaScript and static assets

Front-end behavior, styles and static files ship with the block and are loaded into the page by the platform. Asset paths, bundling and JavaScript runtime expectations can change between named releases, and frontend changes in the micro-frontends follow a different path from legacy XBlock JavaScript. Verify the asset loading method your target release supports and test the block in the browsers your learners use.

Tutor plugin and image build

A block reaches a running platform through the install step, which for Tutor usually means a Tutor plugin that adds the package to the Open edX image build and applies any settings it needs. Pin the block package version and the Tutor version together so that a rebuild produces the same result. Confirm the current plugin hooks and image build steps in the Tutor documentation before writing the plugin.

Custom XBlock, existing block, LTI tool or Tutor plugin: which fits

This table compares the four options a team usually weighs when a course needs something Open edX does not provide out of the box. Read each row against your content, your grading needs and the team that will maintain the result after go-live. The main takeaway is that a custom XBlock is justified mainly when content must live inside the course and report to the gradebook, while an external tool or a platform plugin is often the lighter choice.

OptionWhen it fitsOperational cost to plan for
Existing XBlock or standard componentThe need is covered by problem types, video, discussion, HTML or other bundled components, possibly with configuration only. Choose this first when the content can be authored in Studio.Low ownership cost. Confirm each bundled component still works on your target named release before you commit course design to it.
Custom XBlockInteractive graded content must run inside a unit, store learner state, and send scores to the gradebook, for example a branching assessment or a custom lab check.Your team or partner owns the Python and JavaScript code. Plan for upgrade testing against each new named release, since only the latest release is supported, and for packaging and installation in every environment.
External LTI tool embedded in the courseThe content is an external simulation, lab or tool with its own login and its own hosting, and it can return a grade through LTI grade passback.The tool vendor or your team hosts and secures it. Confirm the tool supports LTI Advantage and grade return, and budget for ongoing vendor dependency and availability of the external service.
Tutor plugin or Django pluginYou need to change platform behavior, such as settings, integrations, templates or deployment configuration, without adding a new course component.Plugin code sits on the platform and must follow Tutor and Open edX changes. Test it with every Tutor version upgrade, and keep the plugin out of forks of core code where possible.
Learner data and grades stored by the componentChoose a custom XBlock or LTI tool only if you know where learner state, scores and personal data are stored and who can access them.Custom XBlocks store data in the platform, so retention and access controls become your responsibility. External tools move that responsibility to the vendor, which needs contract and data-processing review.
Testing effort across releasesEach option needs different regression testing when Open edX moves to a new named release. Ask for a test plan that covers gradebook sync, learner state and course import.Custom XBlocks and plugins need the most regression testing. Existing components need the least, and external tools need checks on the LTI connection after each platform upgrade.
Hosting and availabilityHosting matters when the component runs on your infrastructure, as with custom XBlocks and Tutor plugins, or runs elsewhere, as with an LTI tool.Custom code runs on your LMS and Studio capacity. External tools add a dependency on another system, so confirm its uptime and support terms in writing.
Course team authoringCourse teams need to build and edit the content themselves in Studio, which favors standard components or well-documented XBlocks.Custom XBlocks often need developer changes for each content update. Ask the developer to document the authoring steps and any content fields that course teams can edit.

How to build a custom XBlock from a scoped spec to a deployed block

This sequence takes a custom XBlock from a written spec to a block running in production, with a check that closes each stage. Each step produces an artifact the next step depends on, so gaps surface early. The local environment must meet the platform requirements listed in the local Tutor step.

  1. Write a scoped spec for the block

    The course team and the engineering lead write a spec that defines what learners do with the block, what course authors configure in Studio, and how grading works. The spec should state the score returned for each interaction and the edge cases, such as partial credit, retries and empty submissions. Confirm which Open edX release the block must support, since only the latest named release is supported. The step closes when both parties have reviewed and signed off the spec.

  2. Choose fields and their scope

    Map every piece of data the block needs to a field and an XBlock scope. Settings-scoped fields hold values that course teams edit in Studio, while user-scoped fields hold each learner's state, so check each field against the spec before writing code. Keep grading data in fields the platform's grading machinery can read, and avoid storing learner answers outside the platform. The step closes with a field table reviewed against the spec and checked for scope errors.

  3. Build the author and student views

    Implement the Studio editing view and the LMS student view, along with the handlers that save settings and record submissions. Keep view code thin and place scoring in plain Python functions that tests can call without a running platform. Load static assets such as scripts and stylesheets through the block's resources so they ship inside the package, and reference them from the views. The step closes when the editor saves values and the learner view renders each state described in the spec.

  4. Write unit tests for logic and grading

    Test the scoring functions, field validation and handler responses with unit tests that run without a full platform. Cover each grading rule in the spec, including boundary cases such as empty submissions, retries and maximum scores. Run the suite under Python 3.12 to match the platform. The step closes when every grading rule in the spec has a passing test and the suite runs in the team's continuous integration system, if one exists.

  5. Run the block in local Tutor

    Start a local Tutor development environment, which is the official Docker-based Open edX distribution, with the block installed. Confirm the authoring path in the Studio preview, then enroll a learner test account in the LMS and complete the learner path from the spec. Local development requires Python 3.12, Node.js, MySQL 8.0, MongoDB 7.x and Memcached. The step closes when both paths behave as the spec describes and the grade appears where the spec says it should.

  6. Package the block for Tutor builds

    Package the block as an installable Python package with declared dependencies and an entry point. Then connect it to the platform images through a Tutor plugin, which uses Tutor's hooks system, so the Tutor image build installs it. Pin the block's dependencies to the versions tested in the local step. The step closes when a clean image build includes the block and a freshly started container shows it in Studio.

  7. Deploy to staging and run regression checks

    Deploy the built images to a staging environment that matches production's topology, including the database, cache and media services. For multi-node deployments, confirm a shared Django cache such as Redis or Memcached is configured. Run regression checks: existing courses load, the new block's authoring and learner paths work, grades post correctly, and other custom blocks or plugins still function. The step closes when the checks pass with no open defects and the team has signed off the results.

  8. Promote to production with a rollback plan

    Before promotion, write a rollback plan that names the previous image tag, the steps to restore it, and the person who approves the decision. Back up the databases and media storage, then deploy the same images that passed staging. Watch logs and check grade submissions after release. The step closes when the block works for a learner in production and the owner has confirmed they can revert within the window agreed for the change.

How XBlock packaging changes on a single host, multi-node and Kubernetes

On a single host, Tutor builds the Open edX images locally or from a registry, and a custom XBlock is typically installed as a Python package in a Tutor plugin or a custom image layer. The block is baked into the image, so every change means rebuilding the image and redeploying the stack. Because LMS and Studio run on the same host, there is no mixed-version window to manage, but the restart still interrupts both services.

  • Packaging: Declare the block's Python package in your Tutor plugin or image build so it is present in both the LMS and CMS images.
  • Rebuild: Each block release produces a new image build, which should be tagged so you can identify the exact block version running.
  • Rollout: Redeploy the stack after the build completes. Plan a maintenance window, since both services restart together.
  • Rollback: Keep the previous image tag available and redeploy it if the new block version fails verification.
  • Assets: Confirm that JavaScript assets built by the block are collected and served correctly after each rebuild.

Before any change, confirm the exact Tutor commands for your installed version in the Tutor documentation, because plugin and build commands vary between releases.

What drives XBlock effort and how to keep each driver down

This table lists the factors that move the effort for a custom XBlock and the specific steps that keep each one manageable. Read each row as a decision point: the driver describes what makes the work larger, and the right column describes what your team or a partner can narrow before build starts. The main takeaway is that scope decisions made in the spec, before any code is written, usually matter more than later optimization.

DriverWhy it changes effortHow to keep it down
Interaction types and grading rulesEach interaction type adds a student view, a grading path, and state to store and test. Custom grading logic is the most common source of rework.Limit each block to one or two interaction types in the spec. Reuse standard grading behavior where it fits and write down the grading rules before development starts.
Authoring and learner viewsStudio needs an editing interface and a preview, and the learner view needs its own rendering. Supporting both doubles the surface that must be built and tested.Confirm early whether course teams must edit the block in Studio. Where editing is not needed, keep the authoring view minimal or use existing editors.
Integrations with external services or LMS dataCalls to outside systems, or reads of learner and enrollment data, add credentials, error handling, privacy review, and dependencies that must be mocked in tests.Keep integrations behind a single adapter layer. Ask the data owner which fields are needed and confirm whether the data can come from an existing Open edX API.
Course teams and content variantsMultiple teams or variants multiply the configuration options, fixtures, and course content the block must handle correctly.Agree a fixed set of configuration fields with the course teams. Create a small set of reference courses that cover each variant instead of testing every combination.
Number of environmentsDevelopment, staging, production, and air-gapped environments each need matching builds, images, and configuration. Air-gapped installs also need offline packaging.Build block packages once with Tutor and promote the same artifact through every environment. Confirm with your team how air-gapped packages will be delivered.
Frontend complexityVerawood added new frontend plugin slots and React micro-frontends are used across the platform. Blocks that render custom React components or touch shared frontend code need build and browser testing that legacy blocks do not.Prefer server-rendered views and existing frontend plugin slots where they meet the need. Limit custom JavaScript to the block and confirm slot behavior against the Verawood release notes before design.
Test records and change controlCompliance readiness requires evidence such as test results, peer reviews, and tracked changes, which adds effort to every release of the block.Standardize one test suite with unit and integration tests run in CI. Automate the Tutor build and keep a versioned change log so evidence is produced as a by-product of normal work.

Keeping custom XBlocks working across named Open edX releases

Open edX states that the latest named release is the only supported release and that it cannot support more than one release at a time. For a custom XBlock, this means the block does not get to stay on the version that happened to work at go-live. It has to follow the platform forward. Treat every named release as a planned change to your block, not as an optional upgrade you can defer for years. The current named release is Verawood, published on 30 July 2026. The next releases, Willow and Xylon, are listed for December 2026 and June 2027. Put these dates on your team's calendar and assign an owner for checking each one. Before each release, read its release notes and list the changes that touch your block. Four areas matter most for XBlock authors. First, Python and Django dependency changes, because a block that imports Django internals or pins a library can break when the platform moves its base versions. Second, frontend plugin slots, since a block that injects markup or scripts into Studio or the LMS may depend on a slot that is renamed, moved or removed. Third, Studio changes, such as the new Studio sidebar introduced in Verawood, which can alter how authors reach block settings and actions. Fourth, any change to the XBlock runtime or the way the LMS renders and grades components. Confirm each item against the release notes for that version rather than relying on memory or on a summary from another site. Plan a regression run before each upgrade. Start from a copy of production data or a representative course, install the target release in a non-production environment (for example, with Tutor on a separate instance), and run your automated test suite first. Then walk through the manual paths that automated tests miss: an author editing the block in Studio, a learner completing it in the LMS, a grade appearing in the gradebook, and an instructor viewing the block in the instructor dashboard. Record the results so the next upgrade starts from a known baseline. Ask whether the block's test suite can run against the target release before the upgrade is scheduled, because a block that cannot be tested early will be the last thing ready on upgrade day. After go-live, most of the upkeep is operational. Monitor block errors in both the LMS and Studio logs, and set alerts for exceptions raised from your block's package so that a failure in one component does not hide in general noise. Back up the block source code and its configuration, including any settings passed through Tutor plugins, so that you can rebuild the image without relying on a single developer's workstation. Keep a dependency inventory that lists each package, its version and the reason it is needed, and review it at every release. Document the grading contract as well: what the block sends to the grader, what score scale it uses, and how partial credit is calculated. Finally, hand over the test suite and its run instructions to the team that will own the block after the project closes, and confirm who will carry out the regression run when the next release lands.

The cost of this work is mostly labor, and it recurs. Each named release carries a review, a regression run, and fixes to whatever changed, so the effort depends on how many dependencies your block has, how much it touches the frontend and Studio, and how complete its tests are. A block with a clean test suite and few external dependencies is cheaper to keep current than one that renders custom markup into several plugin slots. When you request a quote, ask for the upgrade work per named release to be stated separately from the initial build, and ask how the vendor will handle a release whose notes contain breaking changes. Confirm all dates and scope with the release notes for each version before you commit to a schedule.

Vetting and securing custom XBlock code

An XBlock runs inside the Open edX platform process, so it carries the same trust as the platform itself. The controls below cover how the code is written, what it can see, what it sends to the browser, and how changes get approved before they reach learners.

Treat blocks as server-side code

An XBlock is Python that runs inside the LMS or Studio process and can read learner records, enrollment data and course content through the APIs it calls. Review every block as trusted server code with the same scrutiny as a platform change. Confirm which user, course and learner data each handler can reach, and limit block code to the data its component actually needs.

Review and pin dependencies

Blocks often pull in third-party Python packages and JavaScript libraries. List every direct and transitive dependency, check each for licence terms and known vulnerabilities, and pin exact versions in the block's requirements and lock files. Re-review pinned versions whenever the Open edX release or Tutor version changes, since a library that works on one platform release may conflict with another.

Keep secrets out of block fields and files

Block fields are stored in course data and static files are served publicly, so neither is a safe place for API keys, passwords or signing secrets. Load secrets from Tutor configuration or the secrets store your team uses, and read them at runtime from settings. Search the block repository and exported course archives for hard-coded credentials before each release.

Filter what reaches the learner

Any value a block sends to the browser, including JSON from handlers, data attributes and rendered HTML, is visible to a learner who opens developer tools. Grading answers, hidden hints and unpublished content must stay on the server. Build learner-facing output from the minimum needed for display, and test each handler by reading its response as a student would.

Verify external calls over TLS

Blocks that call external services, such as video providers, grading tools or content APIs, must use HTTPS and validate the server certificate. Restrict outbound calls to an allowlist of endpoints, set timeouts, and avoid disabling certificate checks for convenience in development settings that could reach production. Confirm how the platform network policy handles egress in your environment.

Set review and change control

Block changes should go through version control with a named reviewer who is not the author, a record of what changed and why, and tests run against a Tutor build before deployment. Keep a rollback path to the last approved version. Where a block depends on third-party authentication or LTI, document that dependency so reviewers check login and grade passback behavior when the block changes. TLS, cookie and admin access settings are covered in the security hardening topic.

How to test an XBlock and confirm it fails safely

An XBlock is ready for a course only after it passes four test layers and shows that it fails without damaging the rest of the course. Start with unit tests for the block's logic and grading functions, run outside the LMS so that scoring changes show up before any learner sees them. Cover boundary scores, empty submissions, malformed input and repeated submissions. Keep these tests in the block's own repository so they run on every change. Confirm that your test setup matches the Python version and tooling used by the edx-platform release you plan to run. The platform's development requirements call for Python 3.12, so check that your block and its dependencies install cleanly on it.

Next, run integration checks in a local Tutor environment. Install the block through a Tutor plugin or a custom image build, then walk through the full authoring cycle in Studio: add the block, edit its settings, save, duplicate it, and export the course. Preview the block in Studio, then open the learner view in the LMS with an enrolled test account. Studio preview and the learner view can take different code paths, so compare what each one renders for the same settings. Record the Tutor version and the named Open edX release you tested against, because both appear in your change record later.

Staging comes next, and it should use course content that resembles production as closely as possible. Load a copy of a real or sanitized course export, then sign in with several learner accounts that cover different states: not started, partially attempted, completed, and retried. Compare the grade reports against expected values for each account. Then run three failure checks. First, make the block raise an exception in one test unit and confirm that the rest of the vertical still renders and the error is logged. Second, remove or disable the block in a staging copy after learners have attempted it, and confirm that progress and grades for other components are unchanged. Third, view the page source as a learner and search for correct answers, hidden feedback or scoring keys. Answers must be checked on the server, not sent to the browser.

Before each platform upgrade, run the full test suite and staging checks again against the target release, because Open edX supports only the latest named release. Confirm that the built Tutor image contains the expected block package at the pinned version and that the block is registered in the image, not just present in a development folder. Keep the previous image tag and its digest so that rollback means redeploying a known image and rerunning smoke tests. Store test logs, screenshots, image digests, version records and sign-off in change control. This evidence supports internal review and audit preparation, but it does not by itself show compliance with any framework. Independent auditors decide that, and DeployOpen prepares the evidence without issuing audit reports or certifications.

Questions teams ask before building a custom XBlock

Is an XBlock the right choice or should we use an LTI tool?

Choose an XBlock when the component must run inside the course, save learner state and appear in Studio as a native component. Choose an LTI tool when the functionality already lives in another system that learners should reach through a launch, and that system can own its data and grading. Check the standard components first, including the built-in problem types and HTML, because many needs are already covered. An XBlock runs in your Open edX code path, so it adds maintenance work that an external tool does not. An LTI tool keeps that code outside the LMS but adds integration and grade passback setup. Write the requirement as learner interaction, data ownership and authoring needs, then compare both options against it in writing before any build is scoped.

What skills and setup does our team need for XBlock work?

The team needs Python and JavaScript skills, working knowledge of Tutor, a staging environment and a named owner for upgrades. Python covers the block's server-side logic and tests. JavaScript covers the student and author views that the block renders in the browser. Tutor familiarity lets developers build a local environment that matches the target Open edX release and package the block as a plugin. A staging environment should mirror production closely enough to test grading, saved state and course content before launch. The named owner tracks each new named release, schedules the test cycle and decides when the block changes. Without that owner, blocks tend to break silently after the first platform upgrade, so assign the role before the build starts.

Can our own team build a custom XBlock without a partner?

Yes, if your team already has the skills listed above and someone can own the block after launch. Many teams start with a small internal prototype in a local Tutor environment, then decide whether to finish it in-house. The decision depends on three points: whether anyone has shipped Open edX code before, how much time developers can spend on testing and support, and how quickly the block must follow each named release. Ask your developers to build a short prototype first and review it against the handover questions later on this page. If the prototype reveals dependencies on LMS internals, or the first packaging and test setup takes longer than planned, a fixed-scope engagement can cover the remaining work with written deliverables.

What drives the cost and time of a custom XBlock build?

The main drivers are how much the block must do, how many learner and author states it handles, and how many other systems it touches. Other factors include the number of Open edX releases you must support, the depth of automated and browser testing, the packaging and deployment path, and whether the block depends only on documented extension points or on LMS internals. The effort-driver table on this page shows how each driver moves the effort, so use it to structure your questions to vendors. No figure is given here because the work depends on the written scope. Ask for the cost to be split into design, build, testing, packaging, handover and the first upgrade, so you can see which parts are one-time and which recur. Ongoing upgrades and support can run as a separate retainer.

How does a new named Open edX release affect our XBlock?

A new named release can break a block, so plan a test cycle for every release you adopt. Open edX states that the latest named release is the only supported release and that it cannot support more than one release at a time, so your block must move with the platform. Verawood is the current named release, published on 30 July 2026, and the next releases, Willow and Xylon, are listed for December 2026 and June 2027. Check the release notes for changed or removed interfaces that your block calls, including Python, Django and frontend plugin APIs. Keep dependencies pinned, keep tests running in continuous integration, and budget upgrade work as a recurring item. Confirm the exact release schedule and changes in the official release notes before you commit to a plan.

How do we test a custom XBlock with Tutor before launch?

Start with a local Tutor environment that matches your target release, then move the block through a staging copy of the platform. Unit tests cover the block's logic, while integration tests run it inside a course in Studio and the LMS, as an author and as a learner would. Agree the browser test scope with your team, including learner roles, devices, course states and grading paths. Keep test data, course fixtures and block configuration in version control so the tests can be rerun after every change. Before launch, run the block against a staging copy of your actual course content and check grading, saved state and accessibility. Ask whether the test suite is part of the handover so your team can run it after go-live.

What should a fixed-scope XBlock quote include?

A fixed-scope quote should list the blocks, their behavior and the acceptance criteria that define done. It should also state the test scope, covering unit, integration and staging runs and which browsers and roles are included. Packaging should be explicit, including the Python package, versioning, installation steps in Tutor and any configuration the block needs. The handover should name the repository access, the runbook, the training session and the owner who receives the work. The upgrade plan should name the release the block targets, who runs the next test cycle and whether that work is a one-off task or a retainer. Finally, list the assumptions the quote depends on, such as who provides the staging environment and course content. DeployOpen agrees fixed scopes, deliverables and timelines in writing before work starts.

How DeployOpen works on this

DeployOpen treats each custom XBlock as a scoped piece of work inside your own Open edX deployment, whether that runs on Tutor or another hosting setup you control. We agree the written scope before development starts, build and test the block against the Open edX release your platform runs, and hand over code, documentation and a verified deployment path.

How we scope

  • Confirm the learning need first, and whether an XBlock is needed instead of an existing component, a frontend plugin or an external LTI tool.
  • Write down the block type, the learner and author interactions, the data it stores and the Studio and LMS views it must provide.
  • Record the target Open edX named release and Tutor version, because only the latest named release is supported and the scope must match it.
  • Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts. Ongoing support is available as a retainer.

How we build

  • Develop the block as a separately packaged Python project that installs into your Tutor image or environment without patching edx-platform itself.
  • Test the block locally with Tutor, covering author views in Studio, learner views in the LMS, grading behavior and course import and export.
  • Check the block against the Python 3.12, Node.js and database versions that the target release expects, and record any version constraints.
  • Review the code for access control, input handling and data storage before it reaches a shared environment, and log the findings.

How we hand over

  • Deliver the source repository, packaging metadata and installation steps so your team can rebuild the block without DeployOpen.
  • Provide developer documentation covering the block's settings, fields, supported Studio and LMS views, and known limitations.
  • Document the test cases run, the environments tested and the steps to repeat the checks after a Tutor or release upgrade.
  • Walk your engineers through deployment, rollback and the upgrade checklist, and confirm which items remain with your team after handover.

How we support

  • Agree in the scope what support follows go-live, such as bug fixes, compatibility checks and help during an Open edX release upgrade.
  • Retest the block against each new named release and Tutor version before your planned upgrade, and report breaking changes early.
  • Offer ongoing support, upgrades and testing as a retainer if your team wants DeployOpen to keep custom blocks working over time.
  • Ask any provider, including us, to confirm response expectations and who owns the code, the documentation and the test suite in writing.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.