diff --git a/Sources/SwiftFormat/API/Configuration+Default.swift b/Sources/SwiftFormat/API/Configuration+Default.swift
index 1af06a121..801e27b1d 100644
--- a/Sources/SwiftFormat/API/Configuration+Default.swift
+++ b/Sources/SwiftFormat/API/Configuration+Default.swift
@@ -42,5 +42,6 @@ extension Configuration {
     self.multiElementCollectionTrailingCommas = true
     self.reflowMultilineStringLiterals = .never
     self.indentBlankLines = false
+    self.alwaysBreakOnNewScopes = false
   }
 }
diff --git a/Sources/SwiftFormat/API/Configuration.swift b/Sources/SwiftFormat/API/Configuration.swift
index 70ac916aa..bc1024381 100644
--- a/Sources/SwiftFormat/API/Configuration.swift
+++ b/Sources/SwiftFormat/API/Configuration.swift
@@ -47,6 +47,7 @@ public struct Configuration: Codable, Equatable {
     case multiElementCollectionTrailingCommas
     case reflowMultilineStringLiterals
     case indentBlankLines
+    case alwaysBreakOnNewScopes
   }
 
   /// A dictionary containing the default enabled/disabled states of rules, keyed by the rules'
@@ -268,6 +269,9 @@ public struct Configuration: Codable, Equatable {
   /// If false (the default), the whitespace in blank lines will be removed entirely.
   public var indentBlankLines: Bool
 
+  /// Determines whether to always break on new scopes.
+  public var alwaysBreakOnNewScopes: Bool
+
   /// Creates a new `Configuration` by loading it from a configuration file.
   public init(contentsOf url: URL) throws {
     let data = try Data(contentsOf: url)
@@ -383,6 +387,10 @@ public struct Configuration: Codable, Equatable {
       )
       ?? defaults.indentBlankLines
 
+    self.alwaysBreakOnNewScopes =
+      try container.decodeIfPresent(Bool.self, forKey: .alwaysBreakOnNewScopes)
+      ?? false
+
     // If the `rules` key is not present at all, default it to the built-in set
     // so that the behavior is the same as if the configuration had been
     // default-initialized. To get an empty rules dictionary, one can explicitly
@@ -422,6 +430,7 @@ public struct Configuration: Codable, Equatable {
     try container.encode(multiElementCollectionTrailingCommas, forKey: .multiElementCollectionTrailingCommas)
     try container.encode(reflowMultilineStringLiterals, forKey: .reflowMultilineStringLiterals)
     try container.encode(rules, forKey: .rules)
+    try container.encode(alwaysBreakOnNewScopes, forKey: .alwaysBreakOnNewScopes)
   }
 
   /// Returns the URL of the configuration file that applies to the given file or directory.
diff --git a/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift
index 03da7d4b4..2c0abd0e5 100644
--- a/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift
+++ b/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift
@@ -3226,20 +3226,27 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
   ) where BodyContents.Element: SyntaxProtocol {
     guard let node = node, let contentsKeyPath = contentsKeyPath else { return }
 
+    let isEmpty = areBracesCompletelyEmpty(node, contentsKeyPath: contentsKeyPath)
+    let newlineBehavior: NewlineBehavior
+    if config.alwaysBreakOnNewScopes && !isEmpty {
+      // Force a newline after the left brace.
+      newlineBehavior = .hard(count: 1)
+    } else {
+      newlineBehavior = openBraceNewlineBehavior
+    }
+
     if shouldResetBeforeLeftBrace {
       before(
         node.leftBrace,
         tokens: .break(.reset, size: 1, newlines: .elective(ignoresDiscretionary: true))
       )
     }
-    if !areBracesCompletelyEmpty(node, contentsKeyPath: contentsKeyPath) {
-      after(
-        node.leftBrace,
-        tokens: .break(.open, size: 1, newlines: openBraceNewlineBehavior),
-        .open
-      )
+
+    if !isEmpty {
+      after(node.leftBrace, tokens: .break(.open, size: 1, newlines: newlineBehavior), .open)
       before(node.rightBrace, tokens: .break(.close, size: 1), .close)
     } else {
+      // If empty scope, keep on the same line if allowed.
       after(node.leftBrace, tokens: .break(.open, size: 0, newlines: openBraceNewlineBehavior))
       before(node.rightBrace, tokens: .break(.close, size: 0))
     }
diff --git a/Tests/SwiftFormatTests/PrettyPrint/AlwaysBreakOnNewScopesTests.swift b/Tests/SwiftFormatTests/PrettyPrint/AlwaysBreakOnNewScopesTests.swift
new file mode 100644
index 000000000..39fe4cbce
--- /dev/null
+++ b/Tests/SwiftFormatTests/PrettyPrint/AlwaysBreakOnNewScopesTests.swift
@@ -0,0 +1,91 @@
+import SwiftFormat
+
+final class AlwaysBreakOnNewScopesTests: PrettyPrintTestCase {
+  func testAlwaysBreakOnNewScopesEnabled() {
+    let input =
+      """
+      class A {
+        func foo() -> Int { return 1 }
+      }
+      """
+
+    let expected =
+      """
+      class A {
+        func foo() -> Int {
+          return 1
+        }
+      }
+
+      """
+    var config = Configuration.forTesting
+    config.alwaysBreakOnNewScopes = true
+    assertPrettyPrintEqual(input: input, expected: expected, linelength: 80, configuration: config)
+  }
+
+  func testAlwaysBreakOnNewScopesDisabled() {
+    let input =
+      """
+      class A {
+        func foo() -> Int { return 1 }
+      }
+      """
+
+    let expected =
+      """
+      class A {
+        func foo() -> Int { return 1 }
+      }
+
+      """
+    var config = Configuration.forTesting
+    config.alwaysBreakOnNewScopes = false
+    assertPrettyPrintEqual(input: input, expected: expected, linelength: 80, configuration: config)
+  }
+
+  func testAlwaysBreakOnNewScopesUnlessScopeIsEmpty() {
+    let input =
+      """
+      class A {
+        func foo() -> Int { }
+      }
+      """
+
+    let expected =
+      """
+      class A {
+        func foo() -> Int {}
+      }
+
+      """
+    var config = Configuration.forTesting
+    config.alwaysBreakOnNewScopes = true
+    assertPrettyPrintEqual(input: input, expected: expected, linelength: 80, configuration: config)
+  }
+
+  func testAlwaysBreakOnNewScopesNestedScopes() {
+    let input =
+      """
+      class A {
+        func foo() -> Int { if true { 1 } else { 2 } }
+      }
+      """
+
+    let expected =
+      """
+      class A {
+        func foo() -> Int {
+          if true {
+            1
+          } else {
+            2
+          }
+        }
+      }
+
+      """
+    var config = Configuration.forTesting
+    config.alwaysBreakOnNewScopes = true
+    assertPrettyPrintEqual(input: input, expected: expected, linelength: 80, configuration: config)
+  }
+}