diff --git wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-language-pack.php wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-language-pack.php
index 0252d9fe7..dca5c716b 100644
--- wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-language-pack.php
+++ wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/inc/cli/class-language-pack.php
@@ -47,6 +47,9 @@ class Language_Pack extends WP_CLI_Command {
 		] );
 
 		switch ( $type ) {
+			case 'core':
+				$this->generate_core( $slug, $args );
+				break;
 			case 'plugin' :
 				$this->generate_plugin( $slug, $args );
 				break;
@@ -58,6 +61,82 @@ class Language_Pack extends WP_CLI_Command {
 		}
 	}
 
+	/**
+	 * Generates a language pack for core.
+	 *
+	 * Examples:
+	 *   wp @translate wporg-translate language-pack generate core 5.0
+	 *   wp @translate wporg-translate language-pack generate core 5.0 --locale=de
+	 *
+	 * @param string $slug Slug of the core version.
+	 * @param array  $args Extra arguments.
+	 */
+	private function generate_core( $slug, $args ) {
+		$projects = [
+			"wp/$slug"               => 'default',
+			"wp/$slug/admin"         => 'admin',
+			"wp/$slug/admin/network" => 'admin-netwrok',
+			"wp/$slug/cc"            => 'continents-cities',
+		];
+
+		foreach ( $projects as $path => $domain ) {
+			$gp_project = GP::$project->by_path( $path );
+			if ( ! $gp_project ) {
+				WP_CLI::error( "Invalid core path: $path." );
+			}
+
+			$translation_sets = GP::$translation_set->by_project_id( $gp_project->id );
+			if ( ! $translation_sets ) {
+				WP_CLI::error( 'No translation sets available.' );
+			}
+
+			/**
+			 * Filters the arguments passed to the WP-CLI command.
+			 *
+			 * @param array  $args CLI arguments.
+			 * @param string $path Path of the GP Project.
+			 */
+			$args = apply_filters( 'wporg_translate_language_pack_core_args', $args, $path );
+
+			if ( $args['locale'] ) {
+				$translation_sets = wp_list_filter( $translation_sets, [
+					'locale' => $args['locale'],
+					'slug'   => $args['locale-slug'],
+				] );
+			}
+
+			if ( $domain === 'continents-cities' ) {
+				$translation_sets = array_filter( $translation_sets, function ( $set ) {
+					return substr( $set->locale, 0, 3 ) !== 'en_';
+				} );
+			}
+
+			$svn_command  = $this->get_svn_command();
+			$svn_checkout = self::get_temp_directory( $slug );
+
+			$result = $this->execute_command( sprintf(
+				'%s checkout --quiet --depth=empty %s %s 2>&1',
+				$svn_command,
+				escapeshellarg( self::SVN_URL . '/core' ),
+				escapeshellarg( $svn_checkout )
+			) );
+
+			if ( is_wp_error( $result ) ) {
+				WP_CLI::error_multi_line( $result->get_error_data() );
+				WP_CLI::error( 'SVN export failed.' );
+			}
+
+			$data                   = new stdClass();
+			$data->type             = 'core';
+			$data->domain           = $domain;
+			$data->version          = $slug;
+			$data->translation_sets = $translation_sets;
+			$data->gp_project       = $gp_project;
+			$data->svn_checkout     = $svn_checkout;
+			$this->build_language_packs( $data );
+		}
+	}
+
 	/**
 	 * Generates a language pack for a plugin.
 	 *
@@ -374,20 +453,83 @@ class Language_Pack extends WP_CLI_Command {
 	}
 
 	/**
-	 * Builds a PO file for translations.
+	 * Build a mapping of JS files to translation entries occurring in those files.
+	 * Translation entries occurring in other files are added to the 'po' key.
 	 *
-	 * @param GP_Project         $gp_project The GlotPress project.
-	 * @param GP_Locale          $gp_locale  The GlotPress locale.
-	 * @param GP_Translation_Set $set        The translation set.
-	 * @param string             $dest       Destination file name.
-	 * @return string|WP_Error Last updated date on success, WP_Error on failure.
+	 * @param Translation_Entry[] $entries The translation entries to map.
+	 *
+	 * @return array The mapping of sources to translation entries.
 	 */
-	private function build_po_file( $gp_project, $gp_locale, $set, $dest ) {
-		$entries = GP::$translation->for_export( $gp_project, $set, [ 'status' => 'current' ] );
-		if ( ! $entries ) {
-			return new WP_Error( 'no_translations', 'No current translations available.' );
+	private function build_mapping( $entries ) {
+		$mapping = array();
+		foreach ( $entries as $entry ) {
+			/** @var Translation_Entry $entry */
+
+			// Find all unique sources this translation originates from.
+			$sources = array_map( function ( $reference ) {
+				$parts = explode( ':', $reference );
+				$file  = $parts[0];
+
+				if ( substr( $file, -7 ) === '.min.js' ) {
+					return substr( $file, 0, -7 ) . '.js';
+				}
+
+				if ( substr( $file, -3 ) === '.js' ) {
+					return $file;
+				}
+				return 'po';
+			}, $entry->references );
+			// Always add all entries to the PO file.
+			$sources[] = 'po';
+			$sources = array_unique( $sources );
+
+			foreach ( $sources as $source ) {
+				$mapping[ $source ][] = $entry;
+			}
 		}
 
+		return $mapping;
+	}
+
+	/**
+	 * Builds a mapping of JS file names to translation entries.
+	 *
+	 * @param GP_Project          $gp_project The GlotPress project.
+	 * @param GP_Locale           $gp_locale  The GlotPress locale.
+	 * @param GP_Translation_Set  $set        The translation set.
+	 * @param array               $mapping    A mapping of files to translation entries.
+	 * @param string              $base_dest  Destination file name.
+	 * @return array An array of translation files built, may be empty if no translations in JS files exist.
+	 */
+	private function build_json_files(  $gp_project, $gp_locale, $set, $mapping, $base_dest ) {
+		// Export translations for each JS file to a separate translation file.
+		$files  = array();
+		$format = gp_array_get( GP::$formats, 'jed1x' );
+		foreach ( $mapping as $file => $entries ) {
+			$json_content = $format->print_exported_file( $gp_project, $gp_locale, $set, $entries );
+
+			$hash = md5( $file );
+			$dest = "{$base_dest}-{$hash}.json";
+
+			file_put_contents( $dest, $json_content );
+
+			$files[] = $dest;
+		}
+
+		return $files;
+	}
+
+	/**
+	 * Builds a PO file for translations.
+	 *
+	 * @param GP_Project          $gp_project The GlotPress project.
+	 * @param GP_Locale           $gp_locale  The GlotPress locale.
+	 * @param GP_Translation_Set  $set        The translation set.
+	 * @param Translation_Entry[] $entries    The translation entries.
+	 * @param string              $dest       Destination file name.
+	 * @return string|WP_Error Last updated date on success, WP_Error on failure.
+	 */
+	private function build_po_file( $gp_project, $gp_locale, $set, $entries, $dest ) {
 		$format     = gp_array_get( GP::$formats, 'po' );
 		$po_content = $format->print_exported_file( $gp_project, $gp_locale, $set, $entries );
 
@@ -520,25 +662,46 @@ class Language_Pack extends WP_CLI_Command {
 				}
 			}
 
-			$export_directory = "{$data->svn_checkout}/{$data->domain}/{$data->version}/{$wp_locale}";
-			$build_directory  = self::BUILD_DIR . "/{$data->type}s/{$data->domain}/{$data->version}";
-			$filename         = "{$data->domain}-{$wp_locale}";
-			$po_file          = "{$export_directory}/{$filename}.po";
-			$mo_file          = "{$export_directory}/{$filename}.mo";
-			$zip_file         = "{$export_directory}/{$filename}.zip";
-			$build_zip_file   = "{$build_directory}/{$wp_locale}.zip";
+			$working_directory = $data->type === 'core' ?$data->svn_checkout : "{$data->svn_checkout}/{$data->domain}";
+			$export_directory  = "{$working_directory}/{$data->version}/{$wp_locale}";
+			$build_directory   = $data->type === 'core'
+				? self::BUILD_DIR . "/core/{$data->version}"
+				: self::BUILD_DIR . "/{$data->type}s/{$data->domain}/{$data->version}";
+
+			$filename       = $data->domain === 'default' ? "{$data->domain}-{$wp_locale}" : $wp_locale;
+			$json_file_base = "{$export_directory}/{$filename}";
+			$po_file        = "{$export_directory}/{$filename}.po";
+			$mo_file        = "{$export_directory}/{$filename}.mo";
+			$zip_file       = "{$export_directory}/{$filename}.zip";
+			$build_zip_file = "{$build_directory}/{$wp_locale}.zip";
 
 			// Update/create directories.
 			$this->update_svn_directory( $export_directory );
 
+			$entries = GP::$translation->for_export( $data->gp_project, $set, [ 'status' => 'current' ] );
+			if ( ! $entries ) {
+				WP_CLI::warning( "No current translations available for {$wp_locale}." );
+
+				continue;
+			}
+
+			// Build a mapping based on where the translation entries occur and separate the po entries.
+			$mapping    = $this->build_mapping( $entries );
+			$po_entries = array_key_exists( 'po', $mapping ) ? $mapping['po'] : array();
+
+			unset( $mapping['po'] );
+
+			// Create JED json files for each JS file.
+			$json_files = $this->build_json_files( $data->gp_project, $gp_locale, $set, $mapping, $json_file_base );
+
 			// Create PO file.
-			$last_modified = $this->build_po_file( $data->gp_project, $gp_locale, $set, $po_file );
+			$last_modified = $this->build_po_file( $data->gp_project, $gp_locale, $set, $po_entries, $po_file );
 
 			if ( is_wp_error( $last_modified ) ) {
 				WP_CLI::warning( sprintf( "PO generation for {$wp_locale} failed: %s", $last_modified->get_error_message() ) );
 
 				// Clean up.
-				$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+				$this->execute_command( "rm -rf {$working_directory}" );
 
 				continue;
 			}
@@ -555,17 +718,18 @@ class Language_Pack extends WP_CLI_Command {
 				WP_CLI::warning( "MO generation for {$wp_locale} failed." );
 
 				// Clean up.
-				$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+				$this->execute_command( "rm -rf {$working_directory}" );
 
 				continue;
 			}
 
 			// Create ZIP file.
 			$result = $this->execute_command( sprintf(
-				'zip -9 -j %s %s %s 2>&1',
+				'zip -9 -j %s %s %s %s 2>&1',
 				escapeshellarg( $zip_file ),
 				escapeshellarg( $po_file ),
-				escapeshellarg( $mo_file )
+				escapeshellarg( $mo_file ),
+				implode( ' ', array_map( 'escapeshellarg', $json_files ) )
 			) );
 
 			if ( is_wp_error( $result ) ) {
@@ -573,7 +737,7 @@ class Language_Pack extends WP_CLI_Command {
 				WP_CLI::warning( "ZIP generation for {$wp_locale} failed." );
 
 				// Clean up.
-				$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+				$this->execute_command( "rm -rf {$working_directory}" );
 
 				continue;
 			}
@@ -589,7 +753,7 @@ class Language_Pack extends WP_CLI_Command {
 				WP_CLI::warning( "Creating build directories for {$wp_locale} failed." );
 
 				// Clean up.
-				$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+				$this->execute_command( "rm -rf {$working_directory}" );
 
 				continue;
 			}
@@ -606,7 +770,7 @@ class Language_Pack extends WP_CLI_Command {
 				WP_CLI::warning( "Moving ZIP file for {$wp_locale} failed." );
 
 				// Clean up.
-				$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+				$this->execute_command( "rm -rf {$working_directory}" );
 
 				continue;
 			}
@@ -618,7 +782,7 @@ class Language_Pack extends WP_CLI_Command {
 				WP_CLI::warning( sprintf( "Language pack for {$wp_locale} failed: %s", $result->get_error_message() ) );
 
 				// Clean up.
-				$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+				$this->execute_command( "rm -rf {$working_directory}" );
 
 				continue;
 			}
@@ -643,13 +807,13 @@ class Language_Pack extends WP_CLI_Command {
 				WP_CLI::warning( "SVN commit for {$wp_locale} failed." );
 
 				// Clean up.
-				$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+				$this->execute_command( "rm -rf {$working_directory}" );
 
 				continue;
 			}
 
 			// Clean up.
-			$this->execute_command( "rm -rf {$data->svn_checkout}/{$data->domain}" );
+			$this->execute_command( "rm -rf {$working_directory}" );
 
 			WP_CLI::success( "Language pack for {$wp_locale} generated." );
 		}
