Type-safe app configuration: a powerful, emerging way to accelerate product development by Miraan
Aug 6, 2025
Everyone has heard of feature flags: boolean switches in your code that you can flip at runtime for different users, environments, etc. But they are just one part of a much broader best practice called “application configuration”. Big tech companies like Meta and Google have internal tools for structured, type-safe app configuration that help them accelerate development of products and backend services. This talk dives into what app configuration is, how you can use it in React and how it can empower your whole team to move faster, including your nontechnical colleagues.
Bio: Miraan is the founder at Hypertune. He was previously at Meta where he led teams across frontend, mobile, backend and machine learning.
Talk structure
- Refresher on feature flags
- Other kinds of “app configuration”: permission flags, limits, rules, in-app content and more
- How we used app configuration at Meta
- Requirements of an app configuration system
- Live code walkthrough and demo of app configuration in action in a React app
🔗 Conference Website: https://reactandchill.live
👋 Code of Conduct: https://reactandchill.live/code-of-co...
📺 CSharp TV - Dev Streaming Destination http://csharp.tv
🌎 C# Corner - Community of Software and Data Developers
Show More Show Less View Video Transcript
0:03
great uh well great to be here so today
0:06
great uh well great to be here so today
0:06
great uh well great to be here so today I'm going to talk about app
0:09
I'm going to talk about app
0:09
I'm going to talk about app configuration now if you've heard of
0:10
configuration now if you've heard of
0:10
configuration now if you've heard of feature Flags you can think of them as
0:13
feature Flags you can think of them as
0:13
feature Flags you can think of them as the tip of the app configuration shaped
0:16
the tip of the app configuration shaped
0:16
the tip of the app configuration shaped Iceberg now the best way to understand
0:18
Iceberg now the best way to understand
0:18
Iceberg now the best way to understand what app configuration is is to see it
0:21
what app configuration is is to see it
0:21
what app configuration is is to see it in action so let's imagine we're a SAS
0:23
in action so let's imagine we're a SAS
0:23
in action so let's imagine we're a SAS company called
0:25
company called
0:25
company called potion and this is the uh this is our
0:29
potion and this is the uh this is our
0:29
potion and this is the uh this is our mobile app and it's the plans page of
0:31
mobile app and it's the plans page of
0:31
mobile app and it's the plans page of our mobile app where users can subscribe
0:34
our mobile app where users can subscribe
0:34
our mobile app where users can subscribe to one of our paid plans now let's say
0:37
to one of our paid plans now let's say
0:37
to one of our paid plans now let's say the marketing team wants to run a 20%
0:39
the marketing team wants to run a 20%
0:39
the marketing team wants to run a 20% discount across all of the paid plans so
0:42
discount across all of the paid plans so
0:42
discount across all of the paid plans so they ask us the engineering team for
0:45
they ask us the engineering team for
0:45
they ask us the engineering team for help so what we'll do is go into our
0:48
help so what we'll do is go into our
0:48
help so what we'll do is go into our code base and we'll write some code to
0:52
code base and we'll write some code to
0:52
code base and we'll write some code to implement this uh 20% discount for them
0:58
implement this uh 20% discount for them
0:58
implement this uh 20% discount for them so we'll do that and once we're happy
1:03
so we'll do that and once we're happy
1:03
so we'll do that and once we're happy with how that looks we'll deploy it to a
1:05
with how that looks we'll deploy it to a
1:05
with how that looks we'll deploy it to a test or staging environment and and
1:08
test or staging environment and and
1:08
test or staging environment and and we'll send the marketing team a link so
1:10
we'll send the marketing team a link so
1:10
we'll send the marketing team a link so they can test it out and make sure that
1:12
they can test it out and make sure that
1:12
they can test it out and make sure that this discount looks good so they do that
1:16
this discount looks good so they do that
1:16
this discount looks good so they do that and they tell us that the discount looks
1:17
and they tell us that the discount looks
1:17
and they tell us that the discount looks good we're ready for it to go to
1:19
good we're ready for it to go to
1:19
good we're ready for it to go to production so we submit this code to
1:22
production so we submit this code to
1:22
production so we submit this code to production now and then once it's live
1:24
production now and then once it's live
1:24
production now and then once it's live We Tell the marketing team and then they
1:26
We Tell the marketing team and then they
1:26
We Tell the marketing team and then they confirm that it looks good again uh and
1:29
confirm that it looks good again uh and
1:29
confirm that it looks good again uh and the discount
1:30
the discount
1:30
the discount is is running in
1:31
is is running in
1:31
is is running in production but then after a few days the
1:34
production but then after a few days the
1:34
production but then after a few days the marketing team says that they want to
1:36
marketing team says that they want to
1:36
marketing team says that they want to pause the discount so we have to go back
1:39
pause the discount so we have to go back
1:39
pause the discount so we have to go back into the code base and make the change
1:42
into the code base and make the change
1:42
into the code base and make the change to disable the
1:44
to disable the
1:44
to disable the discount and then we have to deploy this
1:46
discount and then we have to deploy this
1:46
discount and then we have to deploy this to production which takes some time and
1:49
to production which takes some time and
1:50
to production which takes some time and then we'll tell the marketing team it's
1:51
then we'll tell the marketing team it's
1:51
then we'll tell the marketing team it's paused they confirm that it's paused uh
1:54
paused they confirm that it's paused uh
1:54
paused they confirm that it's paused uh and then we don't hear from them for a
1:55
and then we don't hear from them for a
1:55
and then we don't hear from them for a while but then after a few days they get
1:58
while but then after a few days they get
1:58
while but then after a few days they get back to us and they say they're ready to
2:00
back to us and they say they're ready to
2:00
back to us and they say they're ready to resume the
2:01
resume the
2:01
resume the discounts now this is getting a bit
2:05
discounts now this is getting a bit
2:05
discounts now this is getting a bit tedious for us so we decide to put the
2:09
tedious for us so we decide to put the
2:09
tedious for us so we decide to put the discount behind a feature flag that the
2:12
discount behind a feature flag that the
2:12
discount behind a feature flag that the marketing team can toggle on and off
2:14
marketing team can toggle on and off
2:14
marketing team can toggle on and off themselves now we've already set up a
2:16
themselves now we've already set up a
2:16
themselves now we've already set up a feature flag system in our app called
2:18
feature flag system in our app called
2:18
feature flag system in our app called hypertune so what we'll do is go into
2:21
hypertune so what we'll do is go into
2:21
hypertune so what we'll do is go into the UI for
2:24
the UI for
2:24
the UI for hypertune and we'll create a new feature
2:27
hypertune and we'll create a new feature
2:27
hypertune and we'll create a new feature flag and we'll call it
2:30
flag and we'll call it
2:30
flag and we'll call it is Discount
2:31
is Discount
2:31
is Discount enabled and this will be a Boolean uh
2:34
enabled and this will be a Boolean uh
2:34
enabled and this will be a Boolean uh which just means it could be either on
2:36
which just means it could be either on
2:36
which just means it could be either on or off and we'll leave it off for now
2:38
or off and we'll leave it off for now
2:38
or off and we'll leave it off for now and we'll save that then we'll go into
2:41
and we'll save that then we'll go into
2:41
and we'll save that then we'll go into our code base and we'll run npx
2:44
our code base and we'll run npx
2:45
our code base and we'll run npx hypertune to regenerate our type safe
2:48
hypertune to regenerate our type safe
2:48
hypertune to regenerate our type safe client and we'll use the feature flag in
2:51
client and we'll use the feature flag in
2:51
client and we'll use the feature flag in our code so we'll write hypertune do is
2:54
our code so we'll write hypertune do is
2:54
our code so we'll write hypertune do is Discount enabled and we'll pass a full
2:57
Discount enabled and we'll pass a full
2:57
Discount enabled and we'll pass a full back value of false and then will deploy
3:00
back value of false and then will deploy
3:00
back value of false and then will deploy this to production and then we'll tell
3:02
this to production and then we'll tell
3:02
this to production and then we'll tell the marketing team they can now control
3:05
the marketing team they can now control
3:05
the marketing team they can now control whether the discount is enabled from
3:07
whether the discount is enabled from
3:07
whether the discount is enabled from this flag in the UI so right now it's
3:10
this flag in the UI so right now it's
3:10
this flag in the UI so right now it's off but they can flip it on and then hit
3:13
off but they can flip it on and then hit
3:13
off but they can flip it on and then hit save and then the discount
3:16
save and then the discount
3:16
save and then the discount appears so this is great as now they can
3:20
appears so this is great as now they can
3:20
appears so this is great as now they can make changes to the discount themselves
3:23
make changes to the discount themselves
3:23
make changes to the discount themselves without having to ask us every time and
3:25
without having to ask us every time and
3:25
without having to ask us every time and then we don't have to wait for them to
3:27
then we don't have to wait for them to
3:27
then we don't have to wait for them to tell us when the discount should be live
3:29
tell us when the discount should be live
3:29
tell us when the discount should be live so our work streams are decoupled and we
3:31
so our work streams are decoupled and we
3:31
so our work streams are decoupled and we can both move a lot
3:33
can both move a lot
3:33
can both move a lot faster and because it's a flag they can
3:36
faster and because it's a flag they can
3:36
faster and because it's a flag they can also add more complex logic now to say
3:38
also add more complex logic now to say
3:38
also add more complex logic now to say who the discount should be on for so
3:41
who the discount should be on for so
3:41
who the discount should be on for so they actually decide that they only want
3:43
they actually decide that they only want
3:43
they actually decide that they only want to run the discount in the UK so they
3:45
to run the discount in the UK so they
3:45
to run the discount in the UK so they can add a rule to say if the users's
3:49
can add a rule to say if the users's
3:49
can add a rule to say if the users's country is one of this list of countries
3:52
country is one of this list of countries
3:52
country is one of this list of countries and they add the UK here then the
3:54
and they add the UK here then the
3:54
and they add the UK here then the discount is on otherwise for users in
3:57
discount is on otherwise for users in
3:57
discount is on otherwise for users in all the other countries it's off
4:00
all the other countries it's off
4:00
all the other countries it's off and whenever they make a change here
4:01
and whenever they make a change here
4:01
and whenever they make a change here it's updated instantly so they don't
4:03
it's updated instantly so they don't
4:03
it's updated instantly so they don't have to wait for a code deployment or an
4:05
have to wait for a code deployment or an
4:05
have to wait for a code deployment or an app release they can see their changes
4:07
app release they can see their changes
4:07
app release they can see their changes live immediately uh and the other uh
4:11
live immediately uh and the other uh
4:11
live immediately uh and the other uh great thing about having this flag is
4:14
great thing about having this flag is
4:14
great thing about having this flag is they can also run an AB test on the
4:16
they can also run an AB test on the
4:17
they can also run an AB test on the discount so rather than it just be on
4:19
discount so rather than it just be on
4:20
discount so rather than it just be on for everyone they can drop in an AB test
4:23
for everyone they can drop in an AB test
4:23
for everyone they can drop in an AB test here and they can set it on for half of
4:25
here and they can set it on for half of
4:25
here and they can set it on for half of users off for the other half and then
4:27
users off for the other half and then
4:27
users off for the other half and then this would let them measure the impact
4:30
this would let them measure the impact
4:30
this would let them measure the impact of running the discount on the metrics
4:32
of running the discount on the metrics
4:32
of running the discount on the metrics they care about like signups Revenue
4:35
they care about like signups Revenue
4:35
they care about like signups Revenue profit and so
4:36
profit and so
4:37
profit and so on so we don't hear from the marketing
4:39
on so we don't hear from the marketing
4:39
on so we don't hear from the marketing team for a while because this system is
4:41
team for a while because this system is
4:41
team for a while because this system is working pretty well uh they're not
4:44
working pretty well uh they're not
4:44
working pretty well uh they're not bothering us to to change the discount
4:46
bothering us to to change the discount
4:46
bothering us to to change the discount logic um but then one day we hear from
4:49
logic um but then one day we hear from
4:49
logic um but then one day we hear from them and they tell us that instead of
4:52
them and they tell us that instead of
4:52
them and they tell us that instead of running a 20% discount here they want to
4:55
running a 20% discount here they want to
4:55
running a 20% discount here they want to run a 40% discount now the problem is
4:59
run a 40% discount now the problem is
4:59
run a 40% discount now the problem is that there's % was hardcoded in the code
5:03
that there's % was hardcoded in the code
5:03
that there's % was hardcoded in the code base so we need to change it for them to
5:05
base so we need to change it for them to
5:05
base so we need to change it for them to 40% but we could just change it for them
5:08
40% but we could just change it for them
5:08
40% but we could just change it for them but then that would lead to that same
5:09
but then that would lead to that same
5:09
but then that would lead to that same slow back and forth process that we had
5:12
slow back and forth process that we had
5:12
slow back and forth process that we had before we had the feature flag so let's
5:16
before we had the feature flag so let's
5:16
before we had the feature flag so let's see if there's something that we can do
5:17
see if there's something that we can do
5:17
see if there's something that we can do to give them control over this
5:19
to give them control over this
5:19
to give them control over this percentage as
5:22
percentage as
5:22
percentage as well so one thing that we can do is in
5:25
well so one thing that we can do is in
5:25
well so one thing that we can do is in the hypertune UI instead of returning uh
5:29
the hypertune UI instead of returning uh
5:29
the hypertune UI instead of returning uh a true or false Boolean from this flag
5:32
a true or false Boolean from this flag
5:32
a true or false Boolean from this flag we could return a whole discount object
5:35
we could return a whole discount object
5:35
we could return a whole discount object with subfields to say whether the
5:38
with subfields to say whether the
5:38
with subfields to say whether the discount should be on and another field
5:40
discount should be on and another field
5:40
discount should be on and another field to say what the percentage should be so
5:44
to say what the percentage should be so
5:44
to say what the percentage should be so to do that we'll go into the schema in
5:47
to do that we'll go into the schema in
5:47
to do that we'll go into the schema in hypertune and we'll Define a new object
5:51
hypertune and we'll Define a new object
5:51
hypertune and we'll Define a new object type called
5:53
type called
5:53
type called discount uh so we've actually set one up
5:56
discount uh so we've actually set one up
5:56
discount uh so we've actually set one up here already uh and we've got got a
6:00
here already uh and we've got got a
6:00
here already uh and we've got got a field uh this Boolean field uh called is
6:04
field uh this Boolean field uh called is
6:04
field uh this Boolean field uh called is enabled and another field uh called
6:07
enabled and another field uh called
6:07
enabled and another field uh called percentage which is a
6:09
percentage which is a
6:09
percentage which is a float um and we'll remove this field for
6:15
float um and we'll remove this field for
6:15
float um and we'll remove this field for now so we'll deprecate
6:18
now so we'll deprecate
6:18
now so we'll deprecate this uh Boolean flag and we'll add a new
6:22
this uh Boolean flag and we'll add a new
6:22
this uh Boolean flag and we'll add a new flag called
6:24
flag called
6:24
flag called discount and instead of returning a
6:26
discount and instead of returning a
6:26
discount and instead of returning a Boolean we'll return a discount object
6:31
Boolean we'll return a discount object
6:31
Boolean we'll return a discount object type we'll save that and then we'll go
6:34
type we'll save that and then we'll go
6:35
type we'll save that and then we'll go back into the code base and run npx
6:37
back into the code base and run npx
6:37
back into the code base and run npx hypertune to regenerate our
6:40
hypertune to regenerate our
6:40
hypertune to regenerate our client and then we'll see a type error
6:43
client and then we'll see a type error
6:43
client and then we'll see a type error where we're still using that deprecated
6:44
where we're still using that deprecated
6:45
where we're still using that deprecated flag so we'll replace that with a new
6:48
flag so we'll replace that with a new
6:48
flag so we'll replace that with a new flag which is hypertune do
6:50
flag which is hypertune do
6:50
flag which is hypertune do discount do is
6:53
discount do is
6:53
discount do is enabled and we'll also replace this
6:55
enabled and we'll also replace this
6:55
enabled and we'll also replace this hardcoded percentage with hypertune do
6:58
hardcoded percentage with hypertune do
6:58
hardcoded percentage with hypertune do discount
7:00
discount
7:00
discount do percentage and we'll pass a fullback
7:02
do percentage and we'll pass a fullback
7:03
do percentage and we'll pass a fullback value of zero here so we'll deploy this
7:06
value of zero here so we'll deploy this
7:06
value of zero here so we'll deploy this to production and then we'll tell the
7:08
to production and then we'll tell the
7:08
to production and then we'll tell the marketing team that they can now control
7:11
marketing team that they can now control
7:11
marketing team that they can now control whether the discount is on or off just
7:13
whether the discount is on or off just
7:13
whether the discount is on or off just like before but now they can also
7:16
like before but now they can also
7:16
like before but now they can also control the percentage so instead of 20%
7:20
control the percentage so instead of 20%
7:20
control the percentage so instead of 20% they can have 40%
7:23
they can have 40%
7:23
they can have 40% here uh but just like before they can
7:26
here uh but just like before they can
7:26
here uh but just like before they can also have complex logic to say who the
7:29
also have complex logic to say who the
7:29
also have complex logic to say who the discount should be enabled for so they
7:31
discount should be enabled for so they
7:31
discount should be enabled for so they can have it on for specific countries uh
7:35
can have it on for specific countries uh
7:35
can have it on for specific countries uh and they can have that same kind of
7:36
and they can have that same kind of
7:36
and they can have that same kind of logic for the percentage so they can
7:37
logic for the percentage so they can
7:37
logic for the percentage so they can have different percentages for different
7:39
have different percentages for different
7:39
have different percentages for different users or even AB test the percentage to
7:42
users or even AB test the percentage to
7:42
users or even AB test the percentage to see which one which percentage works
7:45
see which one which percentage works
7:45
see which one which percentage works best so they're pretty happy with this
7:47
best so they're pretty happy with this
7:48
best so they're pretty happy with this system uh they're pretty excited and in
7:50
system uh they're pretty excited and in
7:50
system uh they're pretty excited and in their excitement they ask whether they
7:53
their excitement they ask whether they
7:53
their excitement they ask whether they can also control the copy which we show
7:55
can also control the copy which we show
7:55
can also control the copy which we show next to the discount over here as well
7:57
next to the discount over here as well
7:57
next to the discount over here as well so instead of summer sale
8:00
so instead of summer sale
8:00
so instead of summer sale they can have different messaging and
8:02
they can have different messaging and
8:02
they can have different messaging and see which one works
8:04
see which one works
8:04
see which one works best so to do that we'll go back into
8:07
best so to do that we'll go back into
8:07
best so to do that we'll go back into the schema for our discount object type
8:11
the schema for our discount object type
8:11
the schema for our discount object type and we'll add a new field called name
8:15
and we'll add a new field called name
8:15
and we'll add a new field called name which we set to a string and here's
8:17
which we set to a string and here's
8:17
which we set to a string and here's where we'll control the copy that we
8:19
where we'll control the copy that we
8:19
where we'll control the copy that we show to the
8:20
show to the
8:20
show to the user so we'll save that and then we'll
8:23
user so we'll save that and then we'll
8:23
user so we'll save that and then we'll go into our codebase and run npx
8:27
hypertune and then we'll replace this
8:31
hypertune and then we'll replace this
8:31
hypertune and then we'll replace this hardcoded copy with hypertune do
8:35
hardcoded copy with hypertune do
8:35
hardcoded copy with hypertune do discount. name and we'll pass a fullback
8:38
discount. name and we'll pass a fullback
8:39
discount. name and we'll pass a fullback value of just
8:41
value of just
8:41
value of just discount so we'll deploy this to
8:43
discount so we'll deploy this to
8:43
discount so we'll deploy this to production and now the marketing team
8:45
production and now the marketing team
8:45
production and now the marketing team can control the copy of the discount too
8:48
can control the copy of the discount too
8:48
can control the copy of the discount too so by default it's summer sale uh but
8:53
so by default it's summer sale uh but
8:53
so by default it's summer sale uh but like we said they want to test different
8:55
like we said they want to test different
8:55
like we said they want to test different variations of this messaging to see
8:57
variations of this messaging to see
8:57
variations of this messaging to see which one works best so instead of
8:59
which one works best so instead of
8:59
which one works best so instead of sumale they decide to drop in an ABC
9:03
sumale they decide to drop in an ABC
9:03
sumale they decide to drop in an ABC test to test a few different variations
9:06
test to test a few different variations
9:06
test to test a few different variations of this
9:07
of this
9:07
of this copy so they have summer sale summer
9:10
copy so they have summer sale summer
9:10
copy so they have summer sale summer sale ends soon and summer sale ends
9:14
sale ends soon and summer sale ends
9:14
sale ends soon and summer sale ends today
9:15
today
9:15
today [Music]
9:17
[Music]
9:17
[Music] and now instead of running a traditional
9:21
and now instead of running a traditional
9:21
and now instead of running a traditional experiment where they wait for the
9:24
experiment where they wait for the
9:24
experiment where they wait for the experiment to run and then see which
9:26
experiment to run and then see which
9:26
experiment to run and then see which variation works best and then ship that
9:29
variation works best and then ship that
9:29
variation works best and then ship that VAR
9:29
VAR
9:29
VAR to 100% they instead go to the
9:34
to 100% they instead go to the
9:34
to 100% they instead go to the experiment page in hypertune and they
9:38
experiment page in hypertune and they
9:38
experiment page in hypertune and they set it to a machine learning Loop so
9:42
set it to a machine learning Loop so
9:42
set it to a machine learning Loop so that hypertune will automatically
9:45
that hypertune will automatically
9:45
that hypertune will automatically Converge on the best variant over time
9:48
Converge on the best variant over time
9:48
Converge on the best variant over time to maximize the number of
9:50
to maximize the number of
9:50
to maximize the number of upgrades and it can also take into
9:53
upgrades and it can also take into
9:53
upgrades and it can also take into account user attributes to learn if the
9:55
account user attributes to learn if the
9:56
account user attributes to learn if the best variant is different for different
9:58
best variant is different for different
9:58
best variant is different for different types of users
10:01
types of users
10:01
types of users so they're pretty happy with this system
10:03
so they're pretty happy with this system
10:03
so they're pretty happy with this system now they can control the copy
10:06
now they can control the copy
10:06
now they can control the copy automatically personalize it to each
10:09
automatically personalize it to each
10:09
automatically personalize it to each user with machine learning uh control
10:12
user with machine learning uh control
10:12
user with machine learning uh control the percentage and whether the discount
10:14
the percentage and whether the discount
10:14
the percentage and whether the discount is enabled so we don't hear from them
10:17
is enabled so we don't hear from them
10:17
is enabled so we don't hear from them for a long while they're happy using
10:19
for a long while they're happy using
10:19
for a long while they're happy using this
10:20
this
10:20
this system but then one day we hear from
10:24
system but then one day we hear from
10:24
system but then one day we hear from them and they come to us with a complex
10:26
them and they come to us with a complex
10:26
them and they come to us with a complex use case they want to run a 20 20%
10:30
use case they want to run a 20 20%
10:30
use case they want to run a 20 20% discount for all of their users but they
10:33
discount for all of their users but they
10:33
discount for all of their users but they want an additional 10% discount for
10:35
want an additional 10% discount for
10:35
want an additional 10% discount for users who enter a special discount code
10:38
users who enter a special discount code
10:38
users who enter a special discount code so they need a way to run multiple
10:41
so they need a way to run multiple
10:41
so they need a way to run multiple overlapping discounts at the same time
10:44
overlapping discounts at the same time
10:44
overlapping discounts at the same time so now instead of a flag which returns
10:48
so now instead of a flag which returns
10:48
so now instead of a flag which returns just one discount object we actually
10:51
just one discount object we actually
10:51
just one discount object we actually want a flag which returns a list of
10:53
want a flag which returns a list of
10:53
want a flag which returns a list of discount
10:54
discount
10:54
discount objects so we'll deprecate this discount
10:59
objects so we'll deprecate this discount
10:59
objects so we'll deprecate this discount flag and we'll create a new flag called
11:02
flag and we'll create a new flag called
11:02
flag and we'll create a new flag called discounts which returns a list of
11:09
discounts and we'll save that and then
11:12
discounts and we'll save that and then
11:13
discounts and we'll save that and then go back into our codebase uh before we
11:16
go back into our codebase uh before we
11:16
go back into our codebase uh before we before we regenerate regenerate the
11:18
before we regenerate regenerate the
11:18
before we regenerate regenerate the client we'll actually go into the schema
11:21
client we'll actually go into the schema
11:21
client we'll actually go into the schema uh and we'll actually switch into
11:23
uh and we'll actually switch into
11:23
uh and we'll actually switch into graphql mode and we'll see that new
11:26
graphql mode and we'll see that new
11:26
graphql mode and we'll see that new discounts flag that we created
11:29
discounts flag that we created
11:29
discounts flag that we created and we'll actually add an argument to
11:31
and we'll actually add an argument to
11:31
and we'll actually add an argument to this flag called
11:33
this flag called
11:33
this flag called code which will be a string and this
11:36
code which will be a string and this
11:36
code which will be a string and this will be the discount code which the user
11:37
will be the discount code which the user
11:37
will be the discount code which the user enters and we'll be able to use that in
11:40
enters and we'll be able to use that in
11:40
enters and we'll be able to use that in our Logic for the discounts flag so
11:43
our Logic for the discounts flag so
11:43
our Logic for the discounts flag so we'll save
11:44
we'll save
11:44
we'll save that then we'll regenerate our
11:51
client and then we'll see a type eror
11:54
client and then we'll see a type eror
11:54
client and then we'll see a type eror where we're still using this old
11:56
where we're still using this old
11:56
where we're still using this old discount
11:58
discount
11:58
discount flag uh and instead we will use this new
12:02
flag uh and instead we will use this new
12:02
flag uh and instead we will use this new hypertune do discounts
12:04
hypertune do discounts
12:04
hypertune do discounts flag uh and we'll pass in the code that
12:08
flag uh and we'll pass in the code that
12:08
flag uh and we'll pass in the code that the user enters as an argument and then
12:10
the user enters as an argument and then
12:10
the user enters as an argument and then we'll map over each discount converting
12:12
we'll map over each discount converting
12:12
we'll map over each discount converting it into a plain JavaScript object and
12:15
it into a plain JavaScript object and
12:15
it into a plain JavaScript object and then we'll filter them by the discounts
12:17
then we'll filter them by the discounts
12:17
then we'll filter them by the discounts which are
12:19
which are
12:19
which are enabled so we'll deploy all this to
12:21
enabled so we'll deploy all this to
12:21
enabled so we'll deploy all this to production and then we'll tell the
12:23
production and then we'll tell the
12:23
production and then we'll tell the marketing team they can now add as many
12:25
marketing team they can now add as many
12:26
marketing team they can now add as many discounts as they like to this list flag
12:29
discounts as they like to this list flag
12:30
discounts as they like to this list flag so the first thing they do is they add a
12:32
so the first thing they do is they add a
12:32
so the first thing they do is they add a discount called Summer sale which is on
12:35
discount called Summer sale which is on
12:35
discount called Summer sale which is on for everyone and it uh is for
12:40
for everyone and it uh is for
12:40
for everyone and it uh is for 20% and they save that and they can see
12:43
20% and they save that and they can see
12:43
20% and they save that and they can see that live in the app immediately and
12:46
that live in the app immediately and
12:46
that live in the app immediately and then they add a second
12:47
then they add a second
12:47
then they add a second discount but this time it's only enabled
12:51
discount but this time it's only enabled
12:51
discount but this time it's only enabled if the user has entered a special
12:55
if the user has entered a special
12:55
if the user has entered a special code uh which is is react and
13:02
code uh which is is react and
13:02
code uh which is is react and chill uh and otherwise it's off and this
13:06
chill uh and otherwise it's off and this
13:07
chill uh and otherwise it's off and this is for an additional
13:08
is for an additional
13:08
is for an additional 10% and this will be the react and chill
13:13
10% and this will be the react and chill
13:13
10% and this will be the react and chill discount so they save
13:17
discount so they save
13:17
discount so they save that and now we don't see the discount
13:20
that and now we don't see the discount
13:20
that and now we don't see the discount yet but if the user
13:23
yet but if the user
13:23
yet but if the user enters that code
13:34
uh then we'll see that extra 10%
13:38
uh then we'll see that extra 10%
13:38
uh then we'll see that extra 10% discount
13:40
discount
13:40
discount appear cool so just like before they can
13:43
appear cool so just like before they can
13:43
appear cool so just like before they can have complex Logic for each discount to
13:46
have complex Logic for each discount to
13:46
have complex Logic for each discount to say whether it should be on or off or to
13:48
say whether it should be on or off or to
13:48
say whether it should be on or off or to AB test it they can have logic to have
13:52
AB test it they can have logic to have
13:52
AB test it they can have logic to have different percentages depending on which
13:54
different percentages depending on which
13:54
different percentages depending on which users are looking at the discount uh and
13:56
users are looking at the discount uh and
13:56
users are looking at the discount uh and they can use machine learning to
13:58
they can use machine learning to
13:58
they can use machine learning to personalize the copy to each user to
14:00
personalize the copy to each user to
14:00
personalize the copy to each user to maximize the number of upgrades so with
14:03
maximize the number of upgrades so with
14:03
maximize the number of upgrades so with minimal engineering work we've converted
14:06
minimal engineering work we've converted
14:06
minimal engineering work we've converted this simple Boolean feature flag that we
14:09
this simple Boolean feature flag that we
14:09
this simple Boolean feature flag that we had before into this flag which which
14:13
had before into this flag which which
14:13
had before into this flag which which returns a list of discount objects and
14:16
returns a list of discount objects and
14:16
returns a list of discount objects and we've empowered our marketing team with
14:18
we've empowered our marketing team with
14:18
we've empowered our marketing team with this flexible platform to manage
14:20
this flexible platform to manage
14:20
this flexible platform to manage discounts
14:23
themselves now we actually had uh an app
14:26
themselves now we actually had uh an app
14:26
themselves now we actually had uh an app configuration system just like this or
14:28
configuration system just like this or
14:28
configuration system just like this or similar to this
14:29
similar to this
14:29
similar to this uh at meta and it was called uh
14:34
uh at meta and it was called uh
14:34
uh at meta and it was called uh configurator and it was used in a
14:36
configurator and it was used in a
14:36
configurator and it was used in a similar way to
14:40
platformization released a paper on this
14:43
platformization released a paper on this
14:43
platformization released a paper on this called holistic configuration management
14:45
called holistic configuration management
14:45
called holistic configuration management at Facebook and it dives into how
14:47
at Facebook and it dives into how
14:47
at Facebook and it dives into how configurator was used for lots of
14:48
configurator was used for lots of
14:48
configurator was used for lots of different use cases for example it was
14:51
different use cases for example it was
14:51
different use cases for example it was used to configure automated backend jobs
14:55
used to configure automated backend jobs
14:55
used to configure automated backend jobs like user notifications where you can
14:56
like user notifications where you can
14:56
like user notifications where you can configure templates for different
14:58
configure templates for different
14:58
configure templates for different notifications
14:59
notifications
15:00
notifications types pricing billing and discounts like
15:03
types pricing billing and discounts like
15:03
types pricing billing and discounts like we've just shown in the demo permissions
15:06
we've just shown in the demo permissions
15:06
we've just shown in the demo permissions and features available to
15:09
and features available to
15:09
and features available to users API rate limits inapp copy for
15:13
users API rate limits inapp copy for
15:13
users API rate limits inapp copy for guidance error messages tool tips
15:16
guidance error messages tool tips
15:16
guidance error messages tool tips models forms and
15:18
models forms and
15:18
models forms and wizards metrics health checks and alerts
15:22
wizards metrics health checks and alerts
15:22
wizards metrics health checks and alerts search and ranking
15:24
search and ranking
15:25
search and ranking configuration rules policies filters and
15:28
configuration rules policies filters and
15:28
configuration rules policies filters and classification threshold
15:30
classification threshold
15:30
classification threshold machine learning model parameters and
15:32
machine learning model parameters and
15:32
machine learning model parameters and versioning complex rollouts kill
15:34
versioning complex rollouts kill
15:34
versioning complex rollouts kill switches and
15:36
switches and
15:36
switches and experiments constants API keys and third
15:39
experiments constants API keys and third
15:39
experiments constants API keys and third party integration settings and this
15:41
party integration settings and this
15:41
party integration settings and this large long tail of Niche configuration
15:43
large long tail of Niche configuration
15:43
large long tail of Niche configuration use cases but across all of these
15:46
use cases but across all of these
15:46
use cases but across all of these different use cases we got the same high
15:47
different use cases we got the same high
15:47
different use cases we got the same high level benefits number one we decouple
15:50
level benefits number one we decouple
15:50
level benefits number one we decouple dependencies in our organization so we
15:53
dependencies in our organization so we
15:53
dependencies in our organization so we could enable other teams to selfs serve
15:55
could enable other teams to selfs serve
15:55
could enable other teams to selfs serve and make changes themselves without the
15:57
and make changes themselves without the
15:57
and make changes themselves without the slow back and forth Pro process with
16:00
slow back and forth Pro process with
16:00
slow back and forth Pro process with engineering and as Engineers we could
16:02
engineering and as Engineers we could
16:02
engineering and as Engineers we could focus on shipping code to production
16:04
focus on shipping code to production
16:04
focus on shipping code to production without being blocked by other
16:07
without being blocked by other
16:07
without being blocked by other stakeholders number two we got instant
16:09
stakeholders number two we got instant
16:09
stakeholders number two we got instant updates decoupled from code deployments
16:11
updates decoupled from code deployments
16:11
updates decoupled from code deployments and the release
16:13
and the release
16:13
and the release cycle number three once we had all of
16:15
cycle number three once we had all of
16:15
cycle number three once we had all of this configuration we could optimize it
16:17
this configuration we could optimize it
16:18
this configuration we could optimize it with hand tuning AB testing and machine
16:21
with hand tuning AB testing and machine
16:21
with hand tuning AB testing and machine learning number four we reduced
16:23
learning number four we reduced
16:23
learning number four we reduced complexity by extracting all this
16:25
complexity by extracting all this
16:25
complexity by extracting all this configuration logic like user specific
16:27
configuration logic like user specific
16:27
configuration logic like user specific code out of different code bases and
16:29
code out of different code bases and
16:29
code out of different code bases and into a single source of Truth and we
16:31
into a single source of Truth and we
16:31
into a single source of Truth and we also got this clean separation of
16:33
also got this clean separation of
16:33
also got this clean separation of concerns between code and configuration
16:36
concerns between code and configuration
16:36
concerns between code and configuration so we could focus on the high level
16:37
so we could focus on the high level
16:37
so we could focus on the high level logic in our code and worry about the
16:40
logic in our code and worry about the
16:40
logic in our code and worry about the configuration details later or delegate
16:43
configuration details later or delegate
16:43
configuration details later or delegate that to another
16:44
that to another
16:44
that to another stakeholder and number five we got
16:46
stakeholder and number five we got
16:46
stakeholder and number five we got increased flexibility so after writing
16:49
increased flexibility so after writing
16:49
increased flexibility so after writing our code we could configure it in lots
16:50
our code we could configure it in lots
16:50
our code we could configure it in lots of different ways without any extra
16:53
of different ways without any extra
16:53
of different ways without any extra engineering
16:55
engineering
16:55
engineering work so app configuration is great but
16:58
work so app configuration is great but
16:58
work so app configuration is great but how do we go about building a general
17:00
how do we go about building a general
17:00
how do we go about building a general app configuration system that can scale
17:02
app configuration system that can scale
17:02
app configuration system that can scale to complex use
17:04
to complex use
17:04
to complex use cases the first thing we need is a
17:06
cases the first thing we need is a
17:06
cases the first thing we need is a flexible type system to define the
17:09
flexible type system to define the
17:09
flexible type system to define the inputs going into our system like the
17:11
inputs going into our system like the
17:11
inputs going into our system like the current environment or user and the
17:13
current environment or user and the
17:14
current environment or user and the outputs coming out of our system like
17:16
outputs coming out of our system like
17:16
outputs coming out of our system like the feature Flags or the list of
17:18
the feature Flags or the list of
17:18
the feature Flags or the list of discounts or the list of onboarding
17:21
discounts or the list of onboarding
17:21
discounts or the list of onboarding guides in our
17:23
guides in our
17:23
guides in our app the second thing we need is a
17:25
app the second thing we need is a
17:25
app the second thing we need is a flexible configuration language to
17:27
flexible configuration language to
17:27
flexible configuration language to define the L
17:29
define the L
17:29
define the L that Maps those inputs to the outputs so
17:32
that Maps those inputs to the outputs so
17:32
that Maps those inputs to the outputs so we should be able to to we should be
17:34
we should be able to to we should be
17:34
we should be able to to we should be able to embed AB tests and machine
17:35
able to embed AB tests and machine
17:35
able to embed AB tests and machine learning loops into our logic too and we
17:38
learning loops into our logic too and we
17:38
learning loops into our logic too and we need a UI for non-technical people to
17:41
need a UI for non-technical people to
17:41
need a UI for non-technical people to edit the logic
17:42
edit the logic
17:42
edit the logic visually so when we combine those two
17:44
visually so when we combine those two
17:44
visually so when we combine those two ingredients the flexible type system and
17:47
ingredients the flexible type system and
17:47
ingredients the flexible type system and a flexible visual configuration language
17:50
a flexible visual configuration language
17:50
a flexible visual configuration language we can scale to all of those complex use
17:52
we can scale to all of those complex use
17:52
we can scale to all of those complex use cases that we went through
17:54
cases that we went through
17:54
cases that we went through earlier so this is really powerful but
17:57
earlier so this is really powerful but
17:57
earlier so this is really powerful but it's also a bit scary because we're
17:59
it's also a bit scary because we're
17:59
it's also a bit scary because we're moving critical business logic out of
18:01
moving critical business logic out of
18:02
moving critical business logic out of our codebase and into this configuration
18:04
our codebase and into this configuration
18:04
our codebase and into this configuration system so if the system fails or we make
18:07
system so if the system fails or we make
18:07
system so if the system fails or we make an incorrect change it could cause major
18:09
an incorrect change it could cause major
18:09
an incorrect change it could cause major issues like the one crowd strike
18:11
issues like the one crowd strike
18:11
issues like the one crowd strike experienced recently and we also don't
18:14
experienced recently and we also don't
18:14
experienced recently and we also don't want to impact the performance or
18:16
want to impact the performance or
18:17
want to impact the performance or efficiency of our app by depending on a
18:20
efficiency of our app by depending on a
18:20
efficiency of our app by depending on a configuration
18:22
configuration
18:22
configuration system so how can we make the
18:24
system so how can we make the
18:24
system so how can we make the configuration system as safe reliable
18:27
configuration system as safe reliable
18:27
configuration system as safe reliable performant and efficient as our own
18:31
performant and efficient as our own
18:31
performant and efficient as our own code first we can design the SDK to
18:34
code first we can design the SDK to
18:34
code first we can design the SDK to locally evaluate our configuration logic
18:37
locally evaluate our configuration logic
18:37
locally evaluate our configuration logic so it fetches all the configuration
18:39
so it fetches all the configuration
18:39
so it fetches all the configuration logic from the server up front in One
18:41
logic from the server up front in One
18:41
logic from the server up front in One initial Network request and then after
18:44
initial Network request and then after
18:44
initial Network request and then after that there's no dependency on the
18:45
that there's no dependency on the
18:45
that there's no dependency on the network to evaluate configuration so
18:48
network to evaluate configuration so
18:48
network to evaluate configuration so it's super reliable performant and
18:53
it's super reliable performant and
18:53
it's super reliable performant and efficient but we still have that one
18:55
efficient but we still have that one
18:55
efficient but we still have that one initial request which could fail so to
18:58
initial request which could fail so to
18:58
initial request which could fail so to make this more
18:59
make this more
18:59
make this more we can include a snapshot of our
19:01
we can include a snapshot of our
19:01
we can include a snapshot of our configuration logic in our app bundle so
19:04
configuration logic in our app bundle so
19:04
configuration logic in our app bundle so the SDK can use that as a fallback in
19:06
the SDK can use that as a fallback in
19:06
the SDK can use that as a fallback in case it can't initialize from the server
19:09
case it can't initialize from the server
19:09
case it can't initialize from the server and we can also set up a web hook to
19:11
and we can also set up a web hook to
19:11
and we can also set up a web hook to trigger a new build and deploy of our
19:14
trigger a new build and deploy of our
19:14
trigger a new build and deploy of our app whenever the configuration logic
19:16
app whenever the configuration logic
19:16
app whenever the configuration logic changes so we can keep that build time
19:18
changes so we can keep that build time
19:18
changes so we can keep that build time snapshot up to
19:21
snapshot up to
19:21
snapshot up to date and then if we do that we have that
19:24
date and then if we do that we have that
19:24
date and then if we do that we have that if we have that build time snapshot then
19:25
if we have that build time snapshot then
19:25
if we have that build time snapshot then we don't even need to initialize from
19:27
we don't even need to initialize from
19:27
we don't even need to initialize from the server at all and we can use the SDK
19:30
the server at all and we can use the SDK
19:30
the server at all and we can use the SDK in local only offline mode but then we
19:32
in local only offline mode but then we
19:32
in local only offline mode but then we do lose the benefit of being able to
19:34
do lose the benefit of being able to
19:34
do lose the benefit of being able to update the configuration instantly but
19:37
update the configuration instantly but
19:37
update the configuration instantly but with a blended approach where we
19:40
with a blended approach where we
19:40
with a blended approach where we initialize from the server and we have
19:41
initialize from the server and we have
19:41
initialize from the server and we have the build time snapshot we get the best
19:43
the build time snapshot we get the best
19:43
the build time snapshot we get the best of both
19:46
of both
19:46
of both worlds the next thing we can do is that
19:48
worlds the next thing we can do is that
19:48
worlds the next thing we can do is that when we evaluate configuration we can
19:50
when we evaluate configuration we can
19:50
when we evaluate configuration we can also pass hard-coded fullback values for
19:52
also pass hard-coded fullback values for
19:52
also pass hard-coded fullback values for the case when the SDK hasn't initialized
19:55
the case when the SDK hasn't initialized
19:55
the case when the SDK hasn't initialized and when there's no build time snapshot
19:59
and when there's no build time snapshot
19:59
and when there's no build time snapshot and we can also ensure that the
20:00
and we can also ensure that the
20:00
and we can also ensure that the configuration is evaluated with full
20:02
configuration is evaluated with full
20:02
configuration is evaluated with full endtoend typee safety to avoid typos
20:05
endtoend typee safety to avoid typos
20:05
endtoend typee safety to avoid typos catch errors at compile time rather than
20:07
catch errors at compile time rather than
20:07
catch errors at compile time rather than runtime and enable this great developer
20:10
runtime and enable this great developer
20:10
runtime and enable this great developer experience with IDE features like code
20:12
experience with IDE features like code
20:12
experience with IDE features like code completion find all references and js.
20:17
completion find all references and js.
20:17
completion find all references and js. comments and then finally we can Verge
20:19
comments and then finally we can Verge
20:19
comments and then finally we can Verge and control all of our configuration
20:21
and control all of our configuration
20:21
and control all of our configuration logic in a git style history so we can
20:24
logic in a git style history so we can
20:24
logic in a git style history so we can see exactly what changed and when with
20:27
see exactly what changed and when with
20:27
see exactly what changed and when with clean diffs of logic and schema changes
20:31
clean diffs of logic and schema changes
20:31
clean diffs of logic and schema changes and branches the test and preview
20:33
and branches the test and preview
20:33
and branches the test and preview configuration changes before merging
20:35
configuration changes before merging
20:35
configuration changes before merging them into the main branch with a pull
20:37
them into the main branch with a pull
20:37
them into the main branch with a pull request so we manage our configuration
20:39
request so we manage our configuration
20:39
request so we manage our configuration just like we manage our
20:41
just like we manage our
20:41
just like we manage our codebase and we can also layer on team
20:44
codebase and we can also layer on team
20:44
codebase and we can also layer on team roles and permissions to safely onboard
20:46
roles and permissions to safely onboard
20:46
roles and permissions to safely onboard non-technical team members by requiring
20:49
non-technical team members by requiring
20:49
non-technical team members by requiring that all their changes are first
20:50
that all their changes are first
20:50
that all their changes are first reviewed in a pull request so to recap
20:54
reviewed in a pull request so to recap
20:54
reviewed in a pull request so to recap with this local evaluation build time
20:57
with this local evaluation build time
20:57
with this local evaluation build time snapshots type saf
20:59
snapshots type saf
20:59
snapshots type saf and git style Version Control we can get
21:01
and git style Version Control we can get
21:01
and git style Version Control we can get a similar level of safety reliability
21:04
a similar level of safety reliability
21:04
a similar level of safety reliability performance and efficiency as our own
21:09
performance and efficiency as our own
21:09
performance and efficiency as our own code there was no tool out there like
21:11
code there was no tool out there like
21:11
code there was no tool out there like this so we built hypertune and here are
21:13
this so we built hypertune and here are
21:13
this so we built hypertune and here are some links to check us out it's free to
21:16
some links to check us out it's free to
21:16
some links to check us out it's free to get started and the setup takes under 10
21:19
get started and the setup takes under 10
21:19
get started and the setup takes under 10 minutes so why did we decide to work on
21:22
minutes so why did we decide to work on
21:22
minutes so why did we decide to work on this well we believe there's a lot of
21:24
this well we believe there's a lot of
21:24
this well we believe there's a lot of slow back and forth that happens in
21:26
slow back and forth that happens in
21:26
slow back and forth that happens in organizations during software
21:28
organizations during software
21:28
organizations during software development
21:30
development
21:30
development there's a lot of waiting for updates to
21:32
there's a lot of waiting for updates to
21:32
there's a lot of waiting for updates to reach production especially for apps
21:34
reach production especially for apps
21:34
reach production especially for apps where they slow release cycle like
21:35
where they slow release cycle like
21:35
where they slow release cycle like mobile apps there's a lot of lwh hanging
21:39
mobile apps there's a lot of lwh hanging
21:39
mobile apps there's a lot of lwh hanging fruit to improve product conversion
21:41
fruit to improve product conversion
21:41
fruit to improve product conversion rates and the overall efficiency of
21:43
rates and the overall efficiency of
21:43
rates and the overall efficiency of software systems especially as they
21:46
software systems especially as they
21:46
software systems especially as they scale there's a lot of complexity in
21:48
scale there's a lot of complexity in
21:48
scale there's a lot of complexity in those software systems that can be
21:50
those software systems that can be
21:50
those software systems that can be simplified and there's a lot of slow
21:53
simplified and there's a lot of slow
21:53
simplified and there's a lot of slow iteration and we believe that app
21:55
iteration and we believe that app
21:55
iteration and we believe that app configuration when done in the right way
21:57
configuration when done in the right way
21:57
configuration when done in the right way can be the solution to
21:59
can be the solution to
21:59
can be the solution to those
22:00
those
22:00
those problems so thanks for listening hope
22:02
problems so thanks for listening hope
22:02
problems so thanks for listening hope you enjoyed the talk
22:09
[Music]
#Programming


