LifterLMS Migration Guide: Moving to LifterLMS Safely
Course content is the easy part of a move to LifterLMS. Enrollments, progress, active subscriptions and URLs are where migrations go wrong, so map…
Read articleIf you want to migrate LearnDash to LifterLMS, the good news is that both are WordPress plugins. Your users, pages, media and theme stay where they are, and only the learning layer changes. The harder news is that the two products model courses differently, so a migration is a mapping exercise, not a button.
This guide is for site owners and developers planning that move. It shows what maps cleanly, what needs a decision, how to carry enrollments and progress across without triggering a flood of emails, and how to keep your URLs and recurring revenue intact.
For the general process that applies to any platform, such as audits, staging and rollback, read our LifterLMS migration guide first. This article covers the LearnDash specifics.
LearnDash stores its content as custom post types: sfwd-courses, sfwd-lessons, sfwd-topic, sfwd-quiz, sfwd-question and sfwd-certificates, plus groups for group management. LifterLMS uses course, section, lesson, llms_quiz, llms_question and llms_certificate. The structures overlap but are not identical.
| LearnDash | LifterLMS | Notes |
|---|---|---|
| Course | Course | Direct match. Description, featured image and categories carry over. |
| Section heading | Section | In LifterLMS every lesson must sit in a section, so sections are required, not optional. |
| Lesson | Lesson | Direct match. |
| Topic | Lesson, or a lesson inside a new section | LifterLMS has no third level. See the next section. |
| Quiz on a lesson | Quiz attached to that lesson | A LifterLMS lesson holds one quiz. |
| Quiz on a topic or the whole course | Quiz on its own lesson | Create a lesson such as "Final assessment" to hold it. |
| Single and multiple choice questions | Multiple Choice | Core question type. |
| Fill in the blank, sorting, essay | Advanced Quizzes add-on types | Paid add-on; otherwise rewrite the question. |
| Assignments | Assignments add-on | Paid add-on; submissions are usually archived, not migrated. |
| Groups and group leaders | Groups add-on | Paid add-on; rebuild groups and re-invite leaders. |
| Certificates | Certificate templates | Rebuild the design in the LifterLMS block-based certificate editor. |
| Course points | No direct equivalent | Use achievements, or GamiPress for points. |
Topics are the biggest structural decision. You have two clean options.
Pick one rule and apply it to every course, so students and reports stay consistent. If a LearnDash lesson has content as well as topics, the first option usually means turning that content into an introductory lesson at the top of the new section.
Quizzes need the same thinking. LifterLMS attaches at most one quiz to a lesson, so a course-level final quiz needs a lesson of its own. If you used lesson progression rules that required passing a quiz, recreate them with the Require Passing Grade on Quiz lesson setting and prerequisites. Our guide to drip content and prerequisites in LifterLMS covers those settings.
There is no importer for LearnDash data in LifterLMS core. The core importer, under LifterLMS > Import, reads LifterLMS's own JSON export files. Your realistic options are:
Whatever you use, run it on a staging copy first and compare counts: courses, lessons, questions, enrolled students and completions, before and after.
LearnDash keeps course access and progress in user meta and its own activity table. LifterLMS keeps enrollments and completions in its own table, wp_lifterlms_user_postmeta: an _status row of enrolled for each course or membership, and an _is_complete row of yes for each completed lesson, section and course. Our article on how LifterLMS stores its data explains that table in detail.
Three details trip up most first attempts:
llms_enroll_student() and llms_mark_complete() run the same hooks as a real enrollment or completion. Welcome emails, certificates and achievements will be sent to every migrated student unless you stop them. Switch off enrollment and completion emails under LifterLMS > Settings > Notifications while you import, and suppress engagements in your script.updated_date column of the _start_date row. If you enroll everyone today, lessons dripped "days after enrollment" lock again for long-standing students. Write the original date back.Here is the core of a WP-CLI script that enrolls students from a CSV exported from LearnDash (email, LifterLMS course ID, original enrollment date) and keeps the original date. Run it with wp eval-file llmsx-import-enrollments.php enrollments.csv, then run wp cache flush.
<?php
// Stop engagements (emails, certificates, achievements) during the import.
add_filter( 'lifterlms_get_engagements', '__return_empty_array' );
global $wpdb;
$handle = fopen( $args[0], 'r' );
fgetcsv( $handle ); // Skip the header row.
while ( false !== ( $row = fgetcsv( $handle ) ) ) {
list( $email, $course_id, $enrolled_at ) = $row;
$user = get_user_by( 'email', $email );
if ( ! $user ) {
WP_CLI::warning( "No user found for {$email}" );
continue;
}
$course_id = absint( $course_id );
if ( ! llms_is_user_enrolled( $user->ID, $course_id ) ) {
llms_enroll_student( $user->ID, $course_id, 'llmsx_learndash_import' );
}
// Restore the original enrollment date so drip schedules stay correct.
$wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->prefix}lifterlms_user_postmeta
SET updated_date = %s
WHERE user_id = %d AND post_id = %d
AND meta_key IN ( '_start_date', '_status', '_enrollment_trigger' )",
$enrolled_at,
$user->ID,
$course_id
)
);
}
fclose( $handle );
WP_CLI::success( 'Enrollments imported.' );
Progress follows the same pattern with llms_mark_complete( $user_id, $lesson_id, 'lesson', 'llmsx_learndash_import' ) for each completed lesson or topic, using your topic mapping to find the right LifterLMS lesson ID. Detailed quiz attempt histories rarely justify the effort; most sites keep the final grade in a note or export and let students start fresh on quizzes.
How you sold courses on LearnDash decides the work here.
Never run both LMS plugins' recurring billing at the same time on a cloned site. A staging copy with live gateway keys can charge real customers.
LifterLMS uses /course/ for single courses, /courses/ for the course archive, and /lesson/ and /quiz/ for lessons and quizzes. You can change these bases in Settings > Permalinks, in the LifterLMS Permalinks section. Check your LearnDash permalink settings, including whether nested URLs were on, and list every public course and lesson URL before you start.
Then either match the old structure where it is simple, or add 301 redirects from each old URL to its new equivalent. Course sales pages matter most for search traffic. Lessons are mostly behind a login, but students bookmark them, so redirect those as well.
Not if you migrate it. Lesson and course completions can be recreated in LifterLMS. Detailed quiz attempt histories are usually not migrated, so keep an export of them.
No. Both plugins use standard WordPress user accounts, so logins are unchanged.
Yes, during the migration. Keep LearnDash active until the move is verified, but make sure only one plugin controls access and billing on the live site at any time.
A handful of simple courses can move in days. Sites with many topics, advanced quiz types, groups or active subscriptions take longer, mostly because of testing.
Start with an inventory: courses, topics, quiz types, groups, certificates, active subscriptions and URLs. That list tells you whether a plugin can do the job or whether you need a scripted migration.
If the site has paying subscribers, groups or a large student base, our LifterLMS migration service plans and runs the move, including dry runs, redirects and subscription handling. Send us your inventory and we will tell you what a safe migration involves.
Course content is the easy part of a move to LifterLMS. Enrollments, progress, active subscriptions and URLs are where migrations go wrong, so map…
Read article
Find out why LifterLMS emails are not arriving and fix it: tell sending failures from delivery failures, set up SMTP and a matching sender address…
Read article
Compare the ways to add community to a LifterLMS site, from lesson comments and bbPress forums to BuddyBoss, the Social Learning add-on and external…
Read articleSkip the trial and error. Get specialist LifterLMS help and ship faster.