diff --git src/wp-admin/css/dashboard.css src/wp-admin/css/dashboard.css
index 72b0230..3c7b618 100644
--- src/wp-admin/css/dashboard.css
+++ src/wp-admin/css/dashboard.css
@@ -518,6 +518,10 @@ form.initial-form.quickpress-open input#title {
 	resize: none;
 }
 
+#quick-press.is-saving .spinner {
+	visibility: inherit;
+}
+
 /* Dashboard Quick Draft - Drafts list */
 
 .js #dashboard_quick_press .drafts {
@@ -541,9 +545,68 @@ form.initial-form.quickpress-open input#title {
 	margin: 0 12px;
 }
 
+#dashboard_quick_press .drafts ul.is-placeholder li {
+	padding: 3px 0;
+	color: transparent;
+}
+
+@-webkit-keyframes loading-fade {
+
+	0% {
+		opacity: 0.5;
+	}
+
+	50% {
+		opacity: 1;
+	}
+
+	100% {
+		opacity: 0.5;
+	}
+}
+
+@keyframes loading-fade {
+
+	0% {
+		opacity: 0.5;
+	}
+
+	50% {
+		opacity: 1;
+	}
+
+	100% {
+		opacity: 0.5;
+	}
+}
+
+#dashboard_quick_press .drafts ul.is-placeholder li:before,
+#dashboard_quick_press .drafts ul.is-placeholder li:after {
+	content: "";
+	display: block;
+	height: 13px;
+	background: #eee;
+	-webkit-animation: loading-fade 1.6s ease-in-out infinite;
+	animation: loading-fade 1.6s ease-in-out infinite;
+}
+
+#dashboard_quick_press .drafts ul.is-placeholder li:before {
+	margin-bottom: 5px;
+	width: 40%;
+}
+
+#dashboard_quick_press .drafts ul.is-placeholder li:after {
+	width: 80%;
+}
+
 #dashboard_quick_press .drafts li {
 	margin-bottom: 1em;
 }
+
+#dashboard_quick_press .drafts li.is-new {
+	background-color: #fffbe5;
+}
+
 #dashboard_quick_press .drafts li time {
 	color: #72777c;
 }
diff --git src/wp-admin/includes/dashboard.php src/wp-admin/includes/dashboard.php
index 0ecf0a2..7107f3a 100644
--- src/wp-admin/includes/dashboard.php
+++ src/wp-admin/includes/dashboard.php
@@ -494,46 +494,54 @@ function wp_dashboard_quick_press( $error_msg = false ) {
 	$post_ID = (int) $post->ID;
 ?>
 
-	<form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press" class="initial-form hide-if-no-js">
-
-		<?php if ( $error_msg ) : ?>
-		<div class="error"><?php echo $error_msg; ?></div>
-		<?php endif; ?>
-
+	<form name="post" method="post" id="quick-press" class="initial-form hide-if-no-js">
+		<div class="notice notice-error notice-alt inline hidden"><p></p></div>
 		<div class="input-text-wrap" id="title-wrap">
-			<label class="screen-reader-text prompt" for="title" id="title-prompt-text">
+			<label class="prompt" for="title" id="title-prompt-text">
 
 				<?php
 				/** This filter is documented in wp-admin/edit-form-advanced.php */
 				echo apply_filters( 'enter_title_here', __( 'Title' ), $post );
 				?>
 			</label>
-			<input type="text" name="post_title" id="title" autocomplete="off" />
+			<input type="text" name="title" id="title" autocomplete="off" />
 		</div>
 
 		<div class="textarea-wrap" id="description-wrap">
-			<label class="screen-reader-text prompt" for="content" id="content-prompt-text"><?php _e( 'What&#8217;s on your mind?' ); ?></label>
+			<label class="prompt" for="content" id="content-prompt-text"><?php _e( 'What&#8217;s on your mind?' ); ?></label>
 			<textarea name="content" id="content" class="mceEditor" rows="3" cols="15" autocomplete="off"></textarea>
 		</div>
-
 		<p class="submit">
-			<input type="hidden" name="action" id="quickpost-action" value="post-quickdraft-save" />
-			<input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />
-			<input type="hidden" name="post_type" value="post" />
-			<?php wp_nonce_field( 'add-post' ); ?>
+			<div class="spinner no-float"></div>
 			<?php submit_button( __( 'Save Draft' ), 'primary', 'save', false, array( 'id' => 'save-post' ) ); ?>
 			<br class="clear" />
 		</p>
 
 	</form>
+	<div id="quick-press-drafts" class="drafts">
+		<p class="view-all" style="display: none;">
+			<a href="<?php echo esc_url( admin_url( 'edit.php?post_status=draft' ) ) ?>" aria-label="<?php esc_attr_e( 'View all drafts' ) ?>"><?php _ex( 'View all', 'drafts' ) ?></a>
+		</p>
+		<h2 class="hide-if-no-js"><?php _e( 'Drafts' ) ?></h2>
+		<ul class="drafts-list is-placeholder">
+			<li><span class="screen-reader-text"><?php _e( 'Loading&hellip;' ) ?></span></li>
+		</ul>
+	</div>
+	<script id="tmpl-item-quick-press-draft" type="text/template">
+		<div class="draft-title">
+			<a href="<?php echo ( esc_url( admin_url( 'post.php?post={{ data.id }}&action=edit' ) ) ); ?>" aria-label="<?php esc_attr_e( 'Edit Post' ) ?>">{{ data.formattedTitle }}</a>
+			<time datetime="{{ data.date }}">{{ data.formattedDate }}</time>
+		</div>
+		{{{ data.formattedContent }}}
+	</script>
 	<?php
-	wp_dashboard_recent_drafts();
 }
 
 /**
  * Show recent drafts of the user on the dashboard.
  *
  * @since 2.7.0
+ * @deprecated 4.8.0
  *
  * @param array $drafts
  */
@@ -548,13 +556,7 @@ function wp_dashboard_recent_drafts( $drafts = false ) {
 			'order'          => 'DESC'
 		);
 
-		/**
-		 * Filters the post query arguments for the 'Recent Drafts' dashboard widget.
-		 *
-		 * @since 4.4.0
-		 *
-		 * @param array $query_args The query arguments for the 'Recent Drafts' dashboard widget.
-		 */
+		/** This filter is documented in wp-includes/rest-api.php */
 		$query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args );
 
 		$drafts = get_posts( $query_args );
diff --git src/wp-admin/js/dashboard.js src/wp-admin/js/dashboard.js
index fa100dd..1e914f1 100644
--- src/wp-admin/js/dashboard.js
+++ src/wp-admin/js/dashboard.js
@@ -1,5 +1,5 @@
-/* global pagenow, ajaxurl, postboxes, wpActiveEditor:true */
-var ajaxWidgets, ajaxPopulateWidgets, quickPressLoad;
+/* global _, wp, quickDraft, pagenow, ajaxurl, postboxes, wpActiveEditor:true */
+var ajaxWidgets, ajaxPopulateWidgets, QuickDraft = {};
 
 jQuery(document).ready( function($) {
 	var welcomePanel = $( '#welcome-panel' ),
@@ -59,69 +59,13 @@ jQuery(document).ready( function($) {
 	};
 	ajaxPopulateWidgets();
 
-	postboxes.add_postbox_toggles(pagenow, { pbshow: ajaxPopulateWidgets } );
-
-	/* QuickPress */
-	quickPressLoad = function() {
-		var act = $('#quickpost-action'), t;
-
-		$( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false );
-
-		t = $('#quick-press').submit( function( e ) {
-			e.preventDefault();
-			$('#dashboard_quick_press #publishing-action .spinner').show();
-			$('#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]').prop('disabled', true);
-
-			$.post( t.attr( 'action' ), t.serializeArray(), function( data ) {
-				// Replace the form, and prepend the published post.
-				$('#dashboard_quick_press .inside').html( data );
-				$('#quick-press').removeClass('initial-form');
-				quickPressLoad();
-				highlightLatestPost();
-				$('#title').focus();
-			});
-
-			function highlightLatestPost () {
-				var latestPost = $('.drafts ul li').first();
-				latestPost.css('background', '#fffbe5');
-				setTimeout(function () {
-					latestPost.css('background', 'none');
-				}, 1000);
-			}
-		} );
-
-		$('#publish').click( function() { act.val( 'post-quickpress-publish' ); } );
-
-		$('#title, #tags-input, #content').each( function() {
-			var input = $(this), prompt = $('#' + this.id + '-prompt-text');
-
-			if ( '' === this.value ) {
-				prompt.removeClass('screen-reader-text');
-			}
-
-			prompt.click( function() {
-				$(this).addClass('screen-reader-text');
-				input.focus();
-			});
-
-			input.blur( function() {
-				if ( '' === this.value ) {
-					prompt.removeClass('screen-reader-text');
-				}
-			});
-
-			input.focus( function() {
-				prompt.addClass('screen-reader-text');
-			});
-		});
+	postboxes.add_postbox_toggles(pagenow, { pbshow: function( id ) {
+		ajaxPopulateWidgets();
 
-		$('#quick-press').on( 'click focusin', function() {
-			wpActiveEditor = 'content';
-		});
-
-		autoResizeTextarea();
-	};
-	quickPressLoad();
+		if ( 'dashboard_quick_press' === id ) {
+			QuickDraft.init();
+		}
+	} } );
 
 	$( '.meta-box-sortables' ).sortable( 'option', 'containment', '#wpwrap' );
 
@@ -186,4 +130,376 @@ jQuery(document).ready( function($) {
 		});
 	}
 
+	autoResizeTextarea();
+
+	if ( jQuery( '#dashboard_quick_press' ).is( ':visible' ) ) {
+		QuickDraft.init();
+	}
+});
+
+// Set up the QuickDraft views.
+QuickDraft.Views = {};
+
+/**
+ * Set up a view object for the quick draft form.
+ *
+ * @since 4.8.0
+ *
+ * @augments wp.Backbone.View
+ */
+QuickDraft.Views.Form = wp.Backbone.View.extend( {
+
+	// Set up our default action handlers.
+	events: {
+
+		// Hide the prompt whena field receives focus.
+		'focus :input': 'hidePrompt',
+
+		// Possibly re-display the prompt when a field looses focus.
+		'blur :input':  'showPrompt',
+
+		// Listen for a reset event, showing all prompts.
+		'reset':        'showAllPrompts',
+
+		// Listed for and handle form submissions.
+		'submit':       'handleFormSubmission'
+	},
+
+	// Initialize the QuickDraft Form view.
+	initialize: function() {
+
+		// Show all prompts in the form to begin.
+		this.showAllPrompts();
+
+		// Rerender if the error state changes.
+		quickDraft.state.on( 'change:errorState', _.bind( this.render, this ) );
+	},
+
+	/**
+	 * Handle toggling of the helper prompts shown inside each field.
+	 *
+	 * Will only show the prompt if the field is empty.
+	 *
+	 * @param  {object}  element Field element containing the helper prompt.
+	 * @param  {boolean} visible Should the prompt be visible?
+	 */
+	togglePrompt: function( element, visible ) {
+		var $input = jQuery( element ),
+			hasContent = $input.val().length > 0;
+
+		// Set the visibility of the elements nearest prompt to passed 'visible' value.
+		jQuery( element ).siblings( '.prompt' ).toggleClass( 'screen-reader-text', ! visible || hasContent );
+	},
+
+	// Show all of the field promts.
+	showAllPrompts: function() {
+
+		// Show all of the field prompts.
+		this.$el.find( ':input' ).each( _.bind( function( i, input ) {
+			_.defer( _.bind( this.togglePrompt, this, input, true ) );
+		}, this ) );
+	},
+
+	/**
+	 * Show the prompt inside a field.
+	 *
+	 * @param {object} event The event triggering this show request.
+	 */
+	showPrompt: function( event ) {
+		this.togglePrompt( event.target, true );
+	},
+
+	/**
+	 * Hide the prompt inside a field.
+	 *
+	 * @param {object} event The event triggering this hide request.
+	 */
+	hidePrompt: function( event ) {
+		this.togglePrompt( event.target, false );
+	},
+
+	/**
+	 * Handle error conditions.
+	 *
+	 * {string} error The error condition, or false to reset.
+	 */
+	setErrorState: function( error ) {
+
+		// Set or reset the app state error condition.
+		quickDraft.state.set( 'errorState', error );
+
+		if ( false !== error ) {
+
+			// Alert screen readers that an error occurred.
+			wp.a11y.speak( error, 'assertive' );
+		}
+
+	},
+
+	/**
+	 * Handle the form submission event.
+	 *
+	 * @param {object} event The form submission event.
+	 */
+	handleFormSubmission: function( event ) {
+		var values,
+			hasValuesToSave = false;
+
+		// Prevent the browser's default form submission handling.
+		event.preventDefault();
+
+		// Prevent double submissions by checking the submitting state.
+		if ( quickDraft.state.get( 'submitting' ) ) {
+			return;
+		}
+
+		// Reset the error state.
+		this.setErrorState( false );
+
+		// Extract the form field values.
+		values = _.reduce( this.$el.serializeArray(), function( memo, field ) {
+			memo[ field.name ] = field.value;
+			hasValuesToSave    = hasValuesToSave || ( '' !== field.value );
+			return memo;
+		}, {} );
+
+		// If the values are all blank, show an error.
+		if ( ! hasValuesToSave ) {
+
+			// Set the error.
+			this.setErrorState( quickDraft.l10n.errorEmptyFields );
+			return;
+		}
+
+		// Save the new values to the model and confirm they are valid.
+		this.model.set( values );
+		if ( ! this.model.isValid() ) {
+			return;
+		}
+
+		// Show a spinner during the callback.
+		this.$el.addClass( 'is-saving' );
+
+
+		// Set the state sbmitting to avoid double saves
+		quickDraft.state.set( 'submitting', true );
+
+		// Trigger the model save.
+		this.model.save()
+
+			// Always remove the spinner.
+			.always(
+				_.bind( function() {
+					this.$el.removeClass( 'is-saving' );
+
+					// Refocus in the title field, hiding its prompt.
+					_.delay( function() { jQuery( '#quick-press input#title' ).focus(); }, 250 );
+
+					// Submission complete
+					quickDraft.state.set( 'submitting', false );
+
+				}, this )
+			)
+
+			// Handle save success.
+			.success(
+				_.bind( function() {
+					// Success! Clear any previous error state.
+					 this.render();
+
+					// Add the post model to the head of our collection.
+					this.collection.add( this.model, { at: 0 } );
+
+					// Create a new post model to contain the form data and reset the form.
+					this.model = new wp.api.models.Post();
+					this.model.on( 'change:errorState', _.bind( this.render, this ) );
+
+					this.el.reset();
+				}, this )
+			)
+
+			// Handle save failure.
+			.error(
+				_.bind( function( model, error ) {
+					var message = '';
+
+					// Try to parse and use the response message.
+					try {
+						message = JSON.parse( error.responseText ).message;
+					} catch( e ) {
+
+						// Fall back to a default error string if the parse fails.
+						message = quickDraft.l10n.error;
+					}
+
+					// Set the app error condition.
+					this.setErrorState( message );
+				}, this )
+			);
+	},
+
+	// Render the form view.
+	render: function() {
+		var $error    = this.$el.find( '.notice-alt' ),
+			errorText = quickDraft.state.get( 'errorState' );
+
+		// Error notice is only visible if error text is set.
+		$error.toggleClass( 'hidden', ! errorText );
+		if ( errorText ) {
+
+			// Note: The inner text transform prevents XSS via html().
+			$error.html( jQuery( '<p />', { text: errorText } ) );
+		}
+	}
+} );
+
+/**
+ * Set up a view object for the Quick Draft list of drafts.
+ *
+ * @since 4.8.0
+ *
+ * @augments wp.Backbone.View
+ */
+QuickDraft.Views.DraftList = wp.Backbone.View.extend( {
+
+	// Initialize the draft list view.
+	initialize: function() {
+
+		// Render the view once the drafts have loaded.
+		this.listenTo( this.collection, 'sync', this.onDraftsLoaded );
+	},
+
+	// Once the drafts have loaded, complete the setup.
+	onDraftsLoaded: function() {
+
+		// Add a listener for new items added to the underlying (draft) post collection.
+		this.listenTo( this.collection, 'add', this.renderNew );
+
+		// Render the view!
+		this.render();
+	},
+
+	// Handle a new item being added to the collection.
+	renderNew: function() {
+
+		// Display highlight effect to first (added) item for one second.
+		var $newEl = this.render().$el.find( 'li:first' ).addClass( 'is-new' );
+		setTimeout( function() {
+			$newEl.removeClass( 'is-new' );
+		}, 1000 );
+
+		// Alert screen readers that a new draft has been added.
+		wp.a11y.speak( quickDraft.l10n.newDraftCreated, 'assertive' );
+	},
+
+	// Render the draft post list view.
+	render: function() {
+
+		// Hide drafts list entirely if no drafts exist.
+		this.$el.toggle( this.collection.length > 0 );
+
+		// Display a 'View All' link if there are more drafts available.
+		this.$el.find( '.view-all' ).toggle( this.collection.hasMore() );
+
+		// Remove the placeholder class and render the models.
+		this.$el.find( '.drafts-list' )
+			.removeClass( 'is-placeholder' )
+			.html(
+				_.map( this.collection.models, function( draft ) {
+					return new QuickDraft.Views.DraftListItem( {
+						model: draft
+					} ).render().el;
+				} )
+			);
+
+		return this;
+	}
 } );
+
+/**
+ * Set up a view object an individual draft in the draft list.
+ *
+ * @since 4.8.0
+ *
+ * @augments wp.Backbone.View
+ */
+QuickDraft.Views.DraftListItem = wp.Backbone.View.extend( {
+	tagName: 'li',
+
+	// Render beased on the passed template.
+	template: wp.template( 'item-quick-press-draft' ),
+
+	// Render a single draft list item.
+	render: function() {
+
+		// Clone the original model attributes, so we can leave the model untouched.
+		var attributes = _.clone( this.model.attributes );
+
+		// Trim the content to 10 words.
+		attributes.formattedContent = wp.formatting.trimWords( attributes.content.rendered, 10 );
+
+		// If the title is missing entirely, add a no title placeholder.
+		attributes.formattedTitle = attributes.title.rendered.length > 0 ? attributes.title.rendered : quickDraft.l10n.noTitle;
+
+		// Format the data using Intl.DateTimeFormat with a fallback to date.toLocaleDateString.
+		var date = new Date( wp.api.utils.parseISO8601( attributes.date + quickDraft.timezoneOffset ) );
+		if ( 'undefined' !== typeof Intl && Intl.DateTimeFormat ) {
+			attributes.formattedDate = new Intl.DateTimeFormat( undefined, {
+				month: 'long',
+				day: 'numeric',
+				year: 'numeric'
+			} ).format( date );
+		} else {
+			attributes.formattedDate = date.toLocaleDateString();
+		}
+
+		// Output the rendered template.
+		this.$el.html( this.template( attributes ) );
+
+		// Continue the rendering chain.
+		return this;
+	}
+} );
+
+
+/**
+ * Initialize the Quick Draft feature.
+ *
+ * @since 4.8.0
+ *
+ */
+QuickDraft.init = function() {
+
+	// Set up a state model to track the application state.
+	quickDraft.state = new Backbone.Model({
+		'errorState': false
+	});
+
+	// Wait for the wp-api client to initialize.
+	wp.api.loadPromise.done( function() {
+
+		// Fetch up to 4 of the current user's recent drafts by extending wp.api.collections.Posts.
+		var draftsCollection = new wp.api.collections.Posts();
+		draftsCollection.fetch( {
+			data: {
+				status: 'draft',
+				author: quickDraft.currentUserId,
+				per_page: 4,
+				order_by: 'date',
+				'quick-draft-post-list': true /* flag passed for back end filters */
+			}
+		} );
+
+		// Drafts list is initialized but not rendered until drafts load.
+		new QuickDraft.Views.DraftList( {
+			el: '#quick-press-drafts',
+			collection: draftsCollection
+		} );
+
+		new QuickDraft.Views.Form( {
+			el: '#quick-press',
+			model: new wp.api.models.Post(),
+			collection: draftsCollection
+		} ).render();
+	});
+};
diff --git src/wp-includes/js/wp-util.js src/wp-includes/js/wp-util.js
index 527441d..bdc7531 100644
--- src/wp-includes/js/wp-util.js
+++ src/wp-includes/js/wp-util.js
@@ -121,4 +121,50 @@ window.wp = window.wp || {};
 		}
 	};
 
+	// wp.formatting
+	// ------
+	//
+	// Tools for formatting strings
+	wp.formatting = {
+		settings: settings.formatting || {},
+
+		/**
+		 * Trims text to a certain number of words.
+		 *
+		 * @see wp_trim_words
+		 *
+		 * @param  {string} text     Text to trim.
+		 * @param  {number} numWords Number of words. Optional, default is 55.
+		 * @param  {string} more     What to append if text needs to be trimmed. Optional, default is '…'.
+		 * @return {string}          Trimmed text.
+		 */
+		trimWords: function( text, numWords, more ) {
+			var words, separator;
+
+			if ( 'undefined' === typeof numWords ) {
+				numWords = 55;
+			}
+
+			if ( 'undefined' === typeof more ) {
+				more = wp.formatting.settings.trimWordsMore;
+			}
+
+			text = text.replace( /[\n\r\t ]+/g, ' ' ).replace( /^ | $/g, '' );
+
+			if ( wp.formatting.settings.trimWordsByCharacter ) {
+				separator = '';
+			} else {
+				separator = ' ';
+			}
+
+			words = text.split( separator );
+
+			if ( words.length <= numWords ) {
+				return words.join( separator );
+			}
+
+			return words.slice( 0, numWords ).join( separator ) + more;
+		}
+	};
+
 }(jQuery));
diff --git src/wp-includes/rest-api.php src/wp-includes/rest-api.php
index 3d0b7ee..3711e32 100644
--- src/wp-includes/rest-api.php
+++ src/wp-includes/rest-api.php
@@ -164,6 +164,37 @@ function rest_api_default_filters() {
 	add_filter( 'rest_post_dispatch', 'rest_send_allow_header', 10, 3 );
 
 	add_filter( 'rest_pre_dispatch', 'rest_handle_options_request', 10, 3 );
+
+	// Legacy filter for Quick Draft recent posts.
+	add_filter( 'rest_post_query', 'rest_filter_quick_draft_query', 10, 2 );
+}
+
+/**
+ * Filter query args used by he Quick Draft recent posts list.
+ *
+ * @param array           $args    Key value array of query var to query value.
+ * @param WP_REST_Request $request The request used.
+ */
+function rest_filter_quick_draft_query( $query_args, $request ) {
+
+	// Only modify Quick Draft queries.
+	$params = $request->get_query_params();
+
+	if ( ! isset( $params['quick-draft-post-list'] ) ) {
+		return $query_args;
+	}
+
+	/**
+	 * Filters the post query arguments for the 'Recent Drafts' dashboard widget.
+	 *
+	 * @since 4.4.0
+	 *
+	 * @param array $query_args The query arguments for the 'Recent Drafts' dashboard widget.
+	 */
+	$query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args );
+
+	return $query_args;
+
 }
 
 /**
diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php
index be32073..c10fa11 100644
--- src/wp-includes/script-loader.php
+++ src/wp-includes/script-loader.php
@@ -336,6 +336,15 @@ function wp_default_scripts( &$scripts ) {
 		'ajax' => array(
 			'url' => admin_url( 'admin-ajax.php', 'relative' ),
 		),
+		'formatting' => array(
+			'trimWordsMore'  => __( '&hellip;' ),
+			/*
+			 * translators: If your word count is based on single characters (e.g. East Asian characters),
+			 * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
+			 * Do not translate into your own language.
+			 */
+			'trimWordsByCharacter' => strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ),
+		),
 	) );
 
 	$scripts->add( 'wp-backbone', "/wp-includes/js/wp-backbone$suffix.js", array('backbone', 'wp-util'), false, 1 );
@@ -721,7 +730,17 @@ function wp_default_scripts( &$scripts ) {
 			'current' => __( 'Current Color' ),
 		) );
 
-		$scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), false, 1 );
+		$scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-api', 'wp-backbone', 'wp-a11y', 'wp-util' ), false, 1 );
+		did_action( 'init' ) && $scripts->localize( 'dashboard', 'quickDraft', array(
+			'currentUserId'  => get_current_user_id(),
+			'l10n' => array(
+				'error'            => __( 'An error has occurred. Please reload the page and try again.' ),
+				'newDraftCreated'  => __( 'Success. A new draft was created.' ),
+				'errorEmptyFields' => __( 'Error. All fields were empty.' ),
+				'noTitle'          => __( '(no title)' ),
+			),
+			'timezoneOffset' => ( get_option( 'gmt_offset' ) >= 0 ? '+' : '-' ) . date( 'H:i', abs( get_option( 'gmt_offset' ) * 3600 ) ),
+		) );
 
 		$scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" );
 
diff --git tests/qunit/index.html tests/qunit/index.html
index 9a17ec2..baf0f46 100644
--- tests/qunit/index.html
+++ tests/qunit/index.html
@@ -61,6 +61,7 @@
 		<script src="wp-admin/js/customize-base.js"></script>
 		<script src="wp-admin/js/customize-header.js"></script>
 		<script src="wp-includes/js/shortcode.js"></script>
+		<script src="wp-includes/js/wp-util.js"></script>
 		<script src="wp-admin/js/customize-controls.js"></script>
 		<script src="wp-admin/js/customize-controls-utils.js"></script>
 		<script src="wp-admin/js/customize-nav-menus.js"></script>
diff --git tests/qunit/wp-includes/js/wp-util.js tests/qunit/wp-includes/js/wp-util.js
new file mode 100644
index 0000000..a627585
--- /dev/null
+++ tests/qunit/wp-includes/js/wp-util.js
@@ -0,0 +1,81 @@
+/* global wp */
+( function( QUnit ) {
+	wp.formatting.settings.trimWordsMore = '&hellip;';
+	QUnit.module( 'wp-util' );
+	var longText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce varius lacinia vehicula. Etiam sapien risus, ultricies ac posuere eu, convallis sit amet augue. Pellentesque urna massa, lacinia vel iaculis eget, bibendum in mauris. Aenean eleifend pulvinar ligula, a convallis eros gravida non. Suspendisse potenti. Pellentesque et odio tortor. In vulputate pellentesque libero, sed dapibus velit mollis viverra. Pellentesque id urna euismod dolor cursus sagittis.';
+
+	QUnit.test( 'wp.formatting.trimWords', function( assert ) {
+		_.each( [
+			{
+				'trimmed': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce varius lacinia vehicula. Etiam sapien risus, ultricies ac posuere eu, convallis sit amet augue. Pellentesque urna massa, lacinia vel iaculis eget, bibendum in mauris. Aenean eleifend pulvinar ligula, a convallis eros gravida non. Suspendisse potenti. Pellentesque et odio tortor. In vulputate pellentesque libero, sed dapibus velit&hellip;',
+				'text': longText,
+				'description': 'Trims to 55 by default.'
+			},
+			{
+				'trimmed': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce varius&hellip;',
+				'text': longText,
+				'length': 10,
+				'description': 'Trims to 10.'
+			},
+			{
+				'trimmed': 'Lorem ipsum dolor sit amet,[...] Read on!',
+				'text': longText,
+				'description': 'Trims to 5 and uses custom more.',
+				'length': 5,
+				'more': '[...] Read on!'
+			},
+			{
+				'trimmed': 'This is some short text.',
+				'text': 'This is some short text.',
+				'description': 'Doesn\'t strip short text.'
+			}
+
+		], function( test ) {
+			assert.equal(
+				wp.formatting.trimWords( test.text, test.length, test.more ),
+				test.trimmed,
+				test.description
+			);
+		} );
+	} );
+} )( window.QUnit );
+( function( QUnit ) {
+	wp.formatting.settings.trimWordsMore = '&hellip;';
+	QUnit.module( 'wp-util' );
+	var longText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce varius lacinia vehicula. Etiam sapien risus, ultricies ac posuere eu, convallis sit amet augue. Pellentesque urna massa, lacinia vel iaculis eget, bibendum in mauris. Aenean eleifend pulvinar ligula, a convallis eros gravida non. Suspendisse potenti. Pellentesque et odio tortor. In vulputate pellentesque libero, sed dapibus velit mollis viverra. Pellentesque id urna euismod dolor cursus sagittis.';
+
+	QUnit.test( 'wp.formatting.trimWords', function( assert ) {
+		_.each( [
+			{
+				'trimmed': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce varius lacinia vehicula. Etiam sapien risus, ultricies ac posuere eu, convallis sit amet augue. Pellentesque urna massa, lacinia vel iaculis eget, bibendum in mauris. Aenean eleifend pulvinar ligula, a convallis eros gravida non. Suspendisse potenti. Pellentesque et odio tortor. In vulputate pellentesque libero, sed dapibus velit&hellip;',
+				'text': longText,
+				'description': 'Trims to 55 by default.'
+			},
+			{
+				'trimmed': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce varius&hellip;',
+				'text': longText,
+				'length': 10,
+				'description': 'Trims to 10.'
+			},
+			{
+				'trimmed': 'Lorem ipsum dolor sit amet,[...] Read on!',
+				'text': longText,
+				'description': 'Trims to 5 and uses custom more.',
+				'length': 5,
+				'more': '[...] Read on!'
+			},
+			{
+				'trimmed': 'This is some short text.',
+				'text': 'This is some short text.',
+				'description': 'Doesn\'t strip short text.'
+			}
+
+		], function( test ) {
+			assert.equal(
+				wp.formatting.trimWords( test.text, test.length, test.more ),
+				test.trimmed,
+				test.description
+			);
+		} );
+	} );
+} )( window.QUnit );
