You can achieve the same outcome not by @Builder.Default but by defining the builder itself with defaults for Lombok:

@Builder
public record FileProperties (
        String directory,
        String name,
        String extension
) {
    public static class FilePropertiesBuilder {
        FilePropertiesBuilder() {
            directory = System.getProperty("user.home");
            name = "New file";
            extension = ".txt";
        }
    }
}

Then to test it:

public static void main(String[] args) {
    System.out.println(FileProperties.builder().build());
}

Output:

FileProperties[directory=/home/me, name=New file, extension=.txt]
Answer from user21063779 on Stack Overflow
Discussions

Records and @Builder
It does not defeat the purpose. Records are immutable data objects. How you initialize them, is up to you and using the builder pattern on big data objects makes sense as sometimes the default record constructor might be inflexible. If you don't want to use lombok (@Builder), this works great: https://github.com/Randgalt/record-builder More on reddit.com
🌐 r/javahelp
12
2
September 2, 2024
ANN: Record Builder – Builder and Withers for Java 16 Records

I've mentioned this here before but now that Java 16 is released I've made a new release compiled with the latest Java 16.

Java 16 introduces Records. While this version of records is fantastic, it's currently missing some important features normally found in data classes: a builder and "with"ers. This project is an annotation processor that creates:

  • a companion builder class for Java records

  • an interface that adds "with" copy methods

  • an annotation that generates a Java record from an Interface template

More on reddit.com
🌐 r/java
8
30
March 16, 2021
Derived Record Creation (Draft JEP)
That composition of withers was really cool! I love how much Pattern Matching prioritizes composition. I also appreciated the identity example. The one where they did obj with {};. That really helps cement the mental model that this is really just a mirror relationship between a constructor and a deconstructor. I think the word they keep using is the Embedding-Projection pair. More on reddit.com
🌐 r/java
47
85
January 24, 2024
InnerBuilder, an IntelliJ IDEA plugin that adds a 'Builder' action to the Generate menu (Alt+Insert) which generates an inner builder class as described in Effective Java.
It's a good starting point. Typically if I am going to create a builder, the builder will have a bit of validation logic erc_, but this could save time More on reddit.com
🌐 r/java
17
51
December 5, 2013
Top answer
1 of 1
23

Records are not “Lombok-lite”

Recreating Lombok is not the purpose of Java record.

The purpose of Java record is to provide an explicit vehicle for transparently communicating shallowly-immutable data.

Technically, records are Java’s nominal tuple. Tuple means an ordered set of fields. Nominal means the fields have names, as does their container. Practically, you can think of a Java record as a struct on steroids.

See the official document for scope and purpose, JEP 395: Records.

So no Builder feature need be provided by default as that lies outside the scope of Java record. However, you can easily create your own Builder for any particular record class.

AI-generated

Actually, you need not write your own Builder implementation. Let a generative AI draft the code on your behalf. (Be sure to review carefully as these AIs are imperfect.)

For example:

write code for a Builder class for the Java record record Person ( String name , LocalDate birth ){}

Ecosia AI chat feature produces:

public record Person(String name, LocalDate birth) {
    
    public static class Builder {
        private String name;
        private LocalDate birth;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder birth(LocalDate birth) {
            this.birth = birth;
            return this;
        }

        public Person build() {
            return new Person(name, birth);
        }
    }
}

That code worked for me, copy-pasted, with no edits needed.

Usage:

Person person = new Person.Builder()
    .birth(LocalDate.of(2001, Month.JANUARY, 23))
    .name("Alice")
    .build();

person.toString() // ➡️ Person[name=Alice, birth=2001-01-23]

Withers

By the way, work is underway to add “withers”, a feature to instantiate a new record object based on the payload values of another. See JEP 468: Derived Record Creation (Preview).

Jakarta Validation

You may want to use Jakarta Validation (previously known as Bean Validation) to verify the validity of your new record object’s state.

Likewise, you might use Jakarta Validation in your Builder implementation.

IDE code generation

Your IDE may have a feature for generating code for a Builder from a given Java Record.

For example, IntelliJ has a built-in feature Replace Constructor with Builder. However that does not work for Java Record. But there is a plugin for that. The Record Builder Plugin can “automatically generate builder classes for your Java Records, JavaBeans and Interfaces, allowing you to select fields and configure the generated builder”.

RecordBuilder library

RecordBuilder is an interesting project that lets you mark a Java record with an annotation. Then RecordBuilder generates code for builders and withers.

I’ve not yet tried using this library, so I cannot vouch for it.

🌐
How to do in Java
howtodoinjava.com › home › java basics › builder pattern for java records
Builder Pattern for Java Records
August 6, 2024 - We use the builder pattern to get a mutable intermediate variable and an immutable final result. Since Java ‘record‘ types are immutable by default, the builder pattern is an excellent match for records.
🌐
GitHub
github.com › Randgalt › record-builder
GitHub - Randgalt/record-builder: Record builder generator for Java records · GitHub
Can be used instead of new NameAndAge(...) */ public static NameAndAge NameAndAge(String name, int age) { return new NameAndAge(name, age); } /** * Return a new builder with all fields set to default Java values */ public static NameAndAgeBuilder builder() { return new NameAndAgeBuilder(); } /** * Return a new builder with all fields set to the values taken from the given record instance */ public static NameAndAgeBuilder builder(NameAndAge from) { return new NameAndAgeBuilder(from.name(), from.age()); } /** * Return a "with"er for an existing record instance */ public static NameAndAgeBuilder
Starred by 921 users
Forked by 70 users
Languages   Java
Find elsewhere
🌐
CodingTechRoom
codingtechroom.com › question › java-record-with-builder-default
How to Use @Builder.Default in Java Records - CodingTechRoom
The @Builder.Default annotation in Java records is used to provide default values for fields when using the Builder pattern.
🌐
Java Code Geeks
javacodegeeks.com › home › core java
Java RecordBuilder Example - Java Code Geeks
August 13, 2025 - Introduced in Java 14 (as a preview) and standardized in Java 16, records are immutable data carriers that reduce boilerplate code. However, they lack a built-in builder pattern, which can be essential when constructing complex objects with many optional parameters or nested structures. ... Automatically generate a type-safe, fluent builder for a given record. Set default values for optional fields without cluttering the constructor.
🌐
Medium
medium.com › @trivajay259 › builder-pattern-for-java-records-f62d884e9973
Builder Pattern for Java Records. The builder pattern aims to provide a… | by Ajay Kumar | Medium
March 12, 2026 - We use the builder pattern to get a mutable intermediate variable and an immutable final result. Since Java ‘record‘ types are immutable by default, the builder pattern is an excellent match for ...
🌐
Baeldung
baeldung.com › home › java › core java › custom constructor in java records
Custom Constructor in Java Records | Baeldung
January 15, 2026 - The StudentRecordV3 record defines a String (id), a Set (hobbies), and a Boolean (active) properties. As we can see, we created a custom constructor that only accepts name and provides default values for other properties.
🌐
Softwaregarden
softwaregarden.dev › en › posts › new-java › records › vs-lombok-yet-again-with-builder-pattern
Java Records tortured with Lombok yet again (builder edition) – SoftwareGarden.dev
April 15, 2021 - Or just stick to JavaBeans. However, maybe there are still other ways to “exploit” Lombok with records and bring it to another level? Maybe this time it could be even somewhat useful? Short answer: no. Currently, there’s no ‘default’ or ‘standard’ builder for records.
🌐
Medium
medium.com › @sskmal › java-records-6736f45a6aa7
Java Records and Builder pattern For Record | by sunimal malkakulage | Medium
August 21, 2024 - While Java records themselves are immutable and provide a canonical constructor by default, there are cases where you might want to build a record in a more incremental or flexible manner, ...
🌐
Medium
medium.com › thefreshwrites › migrating-from-lombok-to-records-in-java-fa2ece28bd68
Migrating From Lombok to Records in Java | by Samuel Catalano | The Fresh Writes | Medium
January 25, 2024 - Should the title or director happen to be null, default values will be allocated. import lombok.Builder; @Builder public class FilmWithLombok { private String title; private String director; private int releaseYear; } // Example of using the ...
🌐
Coderanch
coderanch.com › t › 776593 › code-reviews › engineering › Java-Record-Builder-Practice
Java Record Builder Best Practice (Code Reviews forum at Coderanch)
September 16, 2023 - Paul Clapham wrote: I don't think that is possible with Records -- I found that the first statement in the constructor must be a call to the default constructor using the this keyword (I'm new to this so maybe I'm missing something). The best I could do was: ... There is no way you can get around providing a record type with a canonical constructor that is at least as visible as the type itself. That means that you can't force clients of the record type to use a builder to construct instances of the record type.
🌐
Baeldung
baeldung.com › home › java › a practical guide to recordbuilder in java
A Practical Guide to RecordBuilder in Java | Baeldung
November 12, 2025 - It generates fluent, immutable-friendly builders that remove the need for manual constructors or update methods. Its real strength is balance: flexible updates without losing immutability, and expressive code without boilerplate. Whether we’re building DTOs, API responses, or config objects, it fits naturally into our workflow. With almost no setup, RecordBuilder becomes a powerful tool for clean, scalable Java development.
🌐
Medium
medium.com › @pravin3c › 3-ways-to-create-builder-pattern-for-java-records-441cb3bc94b3
3 Ways to Create Builder Pattern for Java Records | by Pravin Choudhary | Medium
April 5, 2024 - It allows step-by-step construction of complex objects and can be particularly useful when you have several optional parameters. Java record types being immutable, by default, the builder pattern is an excellent match for records.
🌐
javathinking
javathinking.com › blog › java-record-with-builder-default
Java Record with Lombok @Builder.Default: How to Fix Compiler Errors and Set Default Values — javathinking.com
When combined with @Builder.Default, Lombok lets you set default values for fields if they’re not explicitly provided via the builder. However, combining Java Records with Lombok’s @Builder.Default can sometimes lead to unexpected compiler errors or incorrect default value behavior.
🌐
DZone
dzone.com › coding › java › migrating from lombok to records in java
Migrating From Lombok to Records in Java
December 28, 2023 - Records inherently provide immutability, as all fields are marked as final by default. In the record example for the Actor class, the name and birthYear fields are immutable, and no setters are generated.
🌐
Medium
medium.com › @shivamtyagicool › does-the-record-in-java-replaces-builder-pattern-450e9a07c8da
Does the record in java replaces builder pattern? | by Shivam Tyagi | Medium
May 28, 2025 - All fields are mandatory (no optional or default values). The number of fields is small, so the constructor is readable. You don’t need logic during construction (e.g., validation, transformation). public record User(String name, int age, ...