diff --git a/packages/cli-config/src/commands/config/migrate.js b/packages/cli-config/src/commands/config/migrate.js
index f6802e5ee..950eb1303 100644
--- a/packages/cli-config/src/commands/config/migrate.js
+++ b/packages/cli-config/src/commands/config/migrate.js
@@ -71,6 +71,13 @@ export class Migrate extends Command {
     this.log.info('Migrating config file...');
     let format = path.extname(output).replace(/^./, '') || 'yaml';
     let migrated = PercyConfig.migrate(config);
+
+    // prefer kebab-case for yaml
+    if (/^ya?ml$/.test(format)) {
+      migrated = PercyConfig.normalize(migrated, { kebab: true });
+    }
+
+    // stringify to the desired format
     let body = PercyConfig.stringify(format, migrated);
 
     // update the package.json entry via string replacement
diff --git a/packages/config/src/load.js b/packages/config/src/load.js
index b9064ac85..c98187b87 100644
--- a/packages/config/src/load.js
+++ b/packages/config/src/load.js
@@ -81,7 +81,7 @@ export default function load({
   }
 
   // merge found config with overrides and validate
-  config = normalize(config, overrides);
+  config = normalize(config, { overrides });
   let validation = config && validate(config);
 
   if (validation && !validation.result) {
diff --git a/packages/config/src/normalize.js b/packages/config/src/normalize.js
index db527e44d..f17940db9 100644
--- a/packages/config/src/normalize.js
+++ b/packages/config/src/normalize.js
@@ -2,38 +2,56 @@ const { isArray } = Array;
 const { entries, assign } = Object;
 
 // Edge case camelizations
-const CAMELIZE_MAP = {
-  css: 'CSS',
-  javascript: 'JavaScript'
-};
+const CAMELCASE_MAP = new Map([
+  ['css', 'CSS'],
+  ['javascript', 'JavaScript']
+]);
 
 // Converts kebab-cased and snake_cased strings to camelCase.
 const KEBAB_SNAKE_REG = /[-_]([^-_]+)/g;
 
-function camelize(str) {
+function camelcase(str) {
   return str.replace(KEBAB_SNAKE_REG, (match, word) => (
-    CAMELIZE_MAP[word] || (word[0].toUpperCase() + word.slice(1))
+    CAMELCASE_MAP.get(word) || (word[0].toUpperCase() + word.slice(1))
   ));
 }
 
+// Coverts camelCased and snake_cased strings to kebab-case.
+const CAMEL_SNAKE_REG = /([a-z])([A-Z]+)|_([^_]+)/g;
+
+function kebabcase(str) {
+  return Array.from(CAMELCASE_MAP)
+    .reduce((str, [word, camel]) => (
+      str.replace(camel, `-${word}`)
+    ), str)
+    .replace(CAMEL_SNAKE_REG, (match, p, n, w) => (
+      `${p || ''}-${(n || w).toLowerCase()}`
+    ));
+}
+
 // Merges source values into the target object unless empty. When `options.replaceArrays` is truthy,
 // target arrays are replaced by their source arrays rather than concatenated together.
 export function merge(target, source, options) {
   let isSourceArray = isArray(source);
   if (options?.replaceArrays && isSourceArray) return source;
   if (typeof source !== 'object') return source != null ? source : target;
+  let convertcase = options?.kebab ? kebabcase : camelcase;
 
   return entries(source).reduce((result, [key, value]) => {
     value = merge(result?.[key], value, options);
 
     return value == null ? result
       : isSourceArray ? (result || []).concat(value)
-        : assign(result || {}, { [camelize(key)]: value });
+        : assign(result || {}, { [convertcase(key)]: value });
   }, target);
 }
 
 // Recursively reduces config objects and arrays to remove undefined and empty values and rename
-// kebab-case properties to camelCase. Optionally allows deep merging of override values
-export default function normalize(object, overrides) {
-  return merge(merge(undefined, object), overrides);
+// kebab-case properties to camelCase. Optionally allows deep merging of a second overrides
+// argument, and converting keys to kebab-case with a third options.kebab argument.
+export default function normalize(object, options) {
+  object = merge(undefined, object, options);
+  return options?.overrides
+    ? merge(object, options.overrides, options)
+    : object;
 }
diff --git a/packages/config/test/index.test.js b/packages/config/test/index.test.js
index 1d01178ff..665ef5fd3 100644
--- a/packages/config/test/index.test.js
+++ b/packages/config/test/index.test.js
@@ -511,11 +511,31 @@ describe('PercyConfig', () => {
       expect(PercyConfig.normalize({
         'foo-bar': 'baz',
         foo: { bar_baz: 'qux' },
-        'foo_bar-baz': 'qux'
+        'foo_bar-baz': 'qux',
+        'percy-css': '',
+        'enable-javascript': false
       })).toEqual({
         fooBar: 'baz',
         foo: { barBaz: 'qux' },
-        fooBarBaz: 'qux'
+        fooBarBaz: 'qux',
+        percyCSS: '',
+        enableJavaScript: false
+      });
+    });
+
+    it('can converts keys to kebab-case', () => {
+      expect(PercyConfig.normalize({
+        'foo-bar': 'baz',
+        foo: { bar_baz: 'qux' },
+        fooBar_baz: 'qux',
+        percyCSS: '',
+        enableJavaScript: false
+      }, { kebab: true })).toEqual({
+        'foo-bar': 'baz',
+        foo: { 'bar-baz': 'qux' },
+        'foo-bar-baz': 'qux',
+        'percy-css': '',
+        'enable-javascript': false
       });
     });
   });